aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2019-12-08 19:18:38 +0200
committerHenry Jameson <me@hjkos.com>2019-12-08 19:18:38 +0200
commit505fb260610e557e27bbc5d27515337ea07e0e3e (patch)
tree3d912a41270e5c3dc946812404aff5b90bda4ab6
parent1b1620a7551293234d000022886c53e4520517a1 (diff)
better wrapper for websocket
-rw-r--r--src/modules/api.js43
-rw-r--r--src/services/api/api.service.js46
-rw-r--r--src/services/backend_interactor_service/backend_interactor_service.js15
3 files changed, 69 insertions, 35 deletions
diff --git a/src/modules/api.js b/src/modules/api.js
index 185c9db6..593f8498 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -34,36 +34,35 @@ const api = {
// MastoAPI 'User' sockets
startMastoUserSocket (store) {
const { state, dispatch } = store
- state.mastoUserSocket = state.backendInteractor
- .startUserSocket({
- store,
- onMessage: (message) => {
- if (!message) return // pings
- if (message.event === 'notification') {
- dispatch('addNewNotifications', {
- notifications: [message.notification],
- older: false
- })
- } else if (message.event === 'update') {
- dispatch('addNewStatuses', {
- statuses: [message.status],
- userId: false,
- showImmediately: false,
- timeline: 'friends'
- })
- }
+ state.mastoUserSocket = state.backendInteractor.startUserSocket({ store })
+ state.mastoUserSocket.addEventListener(
+ 'message',
+ ({ detail: message }) => {
+ if (!message) return // pings
+ if (message.event === 'notification') {
+ dispatch('addNewNotifications', {
+ notifications: [message.notification],
+ older: false
+ })
+ } else if (message.event === 'update') {
+ dispatch('addNewStatuses', {
+ statuses: [message.status],
+ userId: false,
+ showImmediately: false,
+ timeline: 'friends'
+ })
}
- })
- state.mastoUserSocket.addEventListener('error', error => {
+ }
+ )
+ state.mastoUserSocket.addEventListener('error', ({ detail: error }) => {
console.error('Error in MastoAPI websocket:', error)
})
- state.mastoUserSocket.addEventListener('close', closeEvent => {
+ state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => {
const ignoreCodes = new Set([
1000, // Normal (intended) closure
1001 // Going away
])
const { code } = closeEvent
- console.debug('Socket closure event:', closeEvent)
if (ignoreCodes.has(code)) {
console.debug(`Not restarting socket becasue of closure code ${code} is in ignore list`)
} else {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 7f27564f..c6818df4 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -953,8 +953,52 @@ const MASTODON_STREAMING_EVENTS = new Set([
'filters_changed'
])
+// A thin wrapper around WebSocket API that allows adding a pre-processor to it
+// Uses EventTarget and a CustomEvent to proxy events
+export const ProcessedWS = ({
+ url,
+ preprocessor = handleMastoWS,
+ id = 'Unknown'
+}) => {
+ const eventTarget = new EventTarget()
+ const socket = new WebSocket(url)
+ if (!socket) throw new Error(`Failed to create socket ${id}`)
+ const proxy = (original, eventName, processor = a => a) => {
+ original.addEventListener(eventName, (eventData) => {
+ eventTarget.dispatchEvent(new CustomEvent(
+ eventName,
+ { detail: processor(eventData) }
+ ))
+ })
+ }
+ socket.addEventListener('open', (wsEvent) => {
+ console.debug(`[WS][${id}] Socket connected`, wsEvent)
+ })
+ socket.addEventListener('error', (wsEvent) => {
+ console.debug(`[WS][${id}] Socket errored`, wsEvent)
+ })
+ socket.addEventListener('close', (wsEvent) => {
+ console.debug(
+ `[WS][${id}] Socket disconnected with code ${wsEvent.code}`,
+ wsEvent
+ )
+ })
+ socket.addEventListener('message', (wsEvent) => {
+ console.debug(
+ `[WS][${id}] Message received`,
+ wsEvent
+ )
+ })
+
+ proxy(socket, 'open')
+ proxy(socket, 'close')
+ proxy(socket, 'message', preprocessor)
+ proxy(socket, 'error')
+
+ return eventTarget
+}
+
export const handleMastoWS = (wsEvent) => {
- console.debug('Event', wsEvent)
const { data } = wsEvent
if (!data) return
const parsedEvent = JSON.parse(data)
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 33b79a40..b7372ed0 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -1,4 +1,4 @@
-import apiService, { getMastodonSocketURI, handleMastoWS } from '../api/api.service.js'
+import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.service.js'
import timelineFetcherService from '../timeline_fetcher/timeline_fetcher.service.js'
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
@@ -20,19 +20,10 @@ const backendInteractorService = credentials => ({
return followRequestFetcher.startFetching({ store, credentials })
},
- startUserSocket ({ store, onMessage }) {
+ startUserSocket ({ store }) {
const serv = store.rootState.instance.server.replace('http', 'ws')
const url = serv + getMastodonSocketURI({ credentials, stream: 'user' })
- const socket = new WebSocket(url)
- console.debug('Socket created:', socket)
- if (socket) {
- socket.addEventListener('open', (wsEvent) => console.debug('MastoAPI User WebSocket connection established'))
- socket.addEventListener('message', (wsEvent) => onMessage(handleMastoWS(wsEvent)))
- socket.addEventListener('error', (error) => console.error('MastoApi User WebSocket Error:', error))
- return socket
- } else {
- throw new Error('failed to connect to socket')
- }
+ return ProcessedWS({ url, id: 'User' })
},
...Object.entries(apiService).reduce((acc, [key, func]) => {