mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-15 03:30:39 +03:00
Auto-reconnect to event stream after 20secs timeout
This commit is contained in:
parent
2b1a5f579a
commit
56803d0151
@ -17,7 +17,7 @@ type Broker interface {
|
|||||||
|
|
||||||
type broker struct {
|
type broker struct {
|
||||||
// Events are pushed to this channel by the main events-gathering routine
|
// Events are pushed to this channel by the main events-gathering routine
|
||||||
Notifier chan []byte
|
notifier chan []byte
|
||||||
|
|
||||||
// New client connections
|
// New client connections
|
||||||
newClients chan chan []byte
|
newClients chan chan []byte
|
||||||
@ -32,7 +32,7 @@ type broker struct {
|
|||||||
func NewBroker() Broker {
|
func NewBroker() Broker {
|
||||||
// Instantiate a broker
|
// Instantiate a broker
|
||||||
broker := &broker{
|
broker := &broker{
|
||||||
Notifier: make(chan []byte, 1),
|
notifier: make(chan []byte, 1),
|
||||||
newClients: make(chan chan []byte),
|
newClients: make(chan chan []byte),
|
||||||
closingClients: make(chan chan []byte),
|
closingClients: make(chan chan []byte),
|
||||||
clients: make(map[chan []byte]bool),
|
clients: make(map[chan []byte]bool),
|
||||||
@ -52,7 +52,7 @@ func (broker *broker) SendMessage(event Event) {
|
|||||||
pkg.Name = event.EventName()
|
pkg.Name = event.EventName()
|
||||||
pkg.Event = event
|
pkg.Event = event
|
||||||
data, _ := json.Marshal(pkg)
|
data, _ := json.Marshal(pkg)
|
||||||
broker.Notifier <- data
|
broker.notifier <- data
|
||||||
}
|
}
|
||||||
|
|
||||||
func (broker *broker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
func (broker *broker) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
@ -119,7 +119,7 @@ func (broker *broker) listen() {
|
|||||||
// stop sending them messages.
|
// stop sending them messages.
|
||||||
delete(broker.clients, s)
|
delete(broker.clients, s)
|
||||||
log.Debug("Removed client", "numClients", len(broker.clients))
|
log.Debug("Removed client", "numClients", len(broker.clients))
|
||||||
case event := <-broker.Notifier:
|
case event := <-broker.notifier:
|
||||||
|
|
||||||
// We got a new event from the outside!
|
// We got a new event from the outside!
|
||||||
// Send event to all connected clients
|
// Send event to all connected clients
|
||||||
|
@ -27,7 +27,7 @@ import createAdminStore from './store/createAdminStore'
|
|||||||
import { i18nProvider } from './i18n'
|
import { i18nProvider } from './i18n'
|
||||||
import config from './config'
|
import config from './config'
|
||||||
import { startEventStream } from './eventStream'
|
import { startEventStream } from './eventStream'
|
||||||
import { updateScanStatus } from './actions'
|
import { processEvent } from './actions'
|
||||||
const history = createHashHistory()
|
const history = createHashHistory()
|
||||||
|
|
||||||
if (config.gaTrackingId) {
|
if (config.gaTrackingId) {
|
||||||
@ -59,7 +59,7 @@ const App = () => (
|
|||||||
|
|
||||||
const Admin = (props) => {
|
const Admin = (props) => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
startEventStream((data) => dispatch(updateScanStatus(data)))
|
startEventStream((data) => dispatch(processEvent(data)))
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RAAdmin
|
<RAAdmin
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
export const ACTIVITY_SCAN_STATUS_UPD = 'ACTIVITY_SCAN_STATUS_UPD'
|
|
||||||
|
|
||||||
const actionsMap = { scanStatus: ACTIVITY_SCAN_STATUS_UPD }
|
|
||||||
|
|
||||||
export const updateScanStatus = (data) => {
|
|
||||||
let type = actionsMap[data.name]
|
|
||||||
if (!type) type = 'UNKNOWN'
|
|
||||||
return {
|
|
||||||
type,
|
|
||||||
data: data.data,
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,4 +2,4 @@ export * from './audioplayer'
|
|||||||
export * from './themes'
|
export * from './themes'
|
||||||
export * from './albumView'
|
export * from './albumView'
|
||||||
export * from './dialogs'
|
export * from './dialogs'
|
||||||
export * from './activity'
|
export * from './serverEvents'
|
||||||
|
12
ui/src/actions/serverEvents.js
Normal file
12
ui/src/actions/serverEvents.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export const EVENT_SCAN_STATUS = 'ACTIVITY_SCAN_STATUS_UPD'
|
||||||
|
|
||||||
|
const actionsMap = { scanStatus: EVENT_SCAN_STATUS }
|
||||||
|
|
||||||
|
export const processEvent = (data) => {
|
||||||
|
let type = actionsMap[data.name]
|
||||||
|
if (!type) type = 'EVENT_UNKNOWN'
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
data: data.data,
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
import baseUrl from './utils/baseUrl'
|
import baseUrl from './utils/baseUrl'
|
||||||
import throttle from 'lodash.throttle'
|
import throttle from 'lodash.throttle'
|
||||||
|
|
||||||
// TODO https://stackoverflow.com/a/20060461
|
|
||||||
let es = null
|
let es = null
|
||||||
let dispatchFunc = null
|
let onMessageHandler = null
|
||||||
|
let timeOut = null
|
||||||
|
|
||||||
const getEventStream = () => {
|
const getEventStream = () => {
|
||||||
if (es === null) {
|
if (es === null) {
|
||||||
@ -14,17 +14,31 @@ const getEventStream = () => {
|
|||||||
return es
|
return es
|
||||||
}
|
}
|
||||||
|
|
||||||
export const startEventStream = (func) => {
|
// Reestablish the event stream after 20 secs of inactivity
|
||||||
|
const setTimeout = () => {
|
||||||
|
if (timeOut != null) {
|
||||||
|
window.clearTimeout(timeOut)
|
||||||
|
}
|
||||||
|
timeOut = window.setTimeout(() => {
|
||||||
|
es.close()
|
||||||
|
es = null
|
||||||
|
startEventStream(onMessageHandler)
|
||||||
|
}, 20000)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const startEventStream = (messageHandler) => {
|
||||||
const es = getEventStream()
|
const es = getEventStream()
|
||||||
dispatchFunc = func
|
onMessageHandler = messageHandler
|
||||||
es.onmessage = throttle(
|
es.onmessage = throttle(
|
||||||
(msg) => {
|
(msg) => {
|
||||||
const data = JSON.parse(msg.data)
|
const data = JSON.parse(msg.data)
|
||||||
if (data.name !== 'keepAlive') {
|
if (data.name !== 'keepAlive') {
|
||||||
dispatchFunc(data)
|
onMessageHandler(data)
|
||||||
}
|
}
|
||||||
|
setTimeout() // Reset timeout on every received message
|
||||||
},
|
},
|
||||||
100,
|
100,
|
||||||
{ trailing: true }
|
{ trailing: true }
|
||||||
)
|
)
|
||||||
|
setTimeout()
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ACTIVITY_SCAN_STATUS_UPD } from '../actions'
|
import { EVENT_SCAN_STATUS } from '../actions'
|
||||||
|
|
||||||
export const activityReducer = (
|
export const activityReducer = (
|
||||||
previousState = {
|
previousState = {
|
||||||
@ -8,7 +8,7 @@ export const activityReducer = (
|
|||||||
) => {
|
) => {
|
||||||
const { type, data } = payload
|
const { type, data } = payload
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACTIVITY_SCAN_STATUS_UPD:
|
case EVENT_SCAN_STATUS:
|
||||||
return { ...previousState, scanStatus: data }
|
return { ...previousState, scanStatus: data }
|
||||||
default:
|
default:
|
||||||
return previousState
|
return previousState
|
||||||
|
Loading…
x
Reference in New Issue
Block a user