Skip to content

Commit

Permalink
refactor: refactor webocket
Browse files Browse the repository at this point in the history
- factor out array of sockets
- add element to ICamera interface
-  refactor code to support new structure
- add OTA endpoint to REST API
  • Loading branch information
ZanzyTHEbar committed Mar 24, 2023
1 parent 00eda34 commit d5f70a6
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 82 deletions.
20 changes: 11 additions & 9 deletions GUI/ETVR/src/store/api/restAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@ export const defaultState: IRest = {
}

export const endpointsMap: Map<string, IEndpoint> = new Map<string, IEndpoint>([
['ping', { url: '/control/command/ping', type: RESTType.GET }],
['save', { url: '/control/command/save', type: RESTType.GET }],
['resetConfig', { url: '/control/command/resetConfig', type: RESTType.GET }],
['rebootDevice', { url: '/control/command/rebootDevice', type: RESTType.GET }],
['restartCamera', { url: '/control/command/restartCamera', type: RESTType.GET }],
['getStoredConfig', { url: '/control/command/getStoredConfig', type: RESTType.GET }],
['setTxPower', { url: '/control/command/setTxPower', type: RESTType.POST }],
['setDevice', { url: '/control/command/setDevice', type: RESTType.POST }],
['wifi', { url: '/control/command/wifi', type: RESTType.POST }],
['ping', { url: ':81/control/command/ping', type: RESTType.GET }],
['save', { url: ':81/control/command/save', type: RESTType.GET }],
['resetConfig', { url: ':81/control/command/resetConfig', type: RESTType.GET }],
['rebootDevice', { url: ':81/control/command/rebootDevice', type: RESTType.GET }],
['restartCamera', { url: ':81/control/command/restartCamera', type: RESTType.GET }],
['getStoredConfig', { url: ':81/control/command/getStoredConfig', type: RESTType.GET }],
['setTxPower', { url: ':81/control/command/setTxPower', type: RESTType.POST }],
['setDevice', { url: ':81/control/command/setDevice', type: RESTType.POST }],
['wifi', { url: ':81/control/command/wifi', type: RESTType.POST }],
['wifiStrength', { url: ':81/control/command/wifiStrength', type: RESTType.POST }],
['ota', { url: ':81/update', type: RESTType.POST }],
])

const [state, setState] = createStore<IRest>(defaultState)
Expand Down
2 changes: 0 additions & 2 deletions GUI/ETVR/src/store/api/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,5 @@ export const ghRESTEndpoint = createMemo(() => ghEndpoint)
/********************************* websockets *************************************/
export const rtcStatus = createMemo(() => rtcState().status)
export const rtcMessageType = createMemo(() => rtcState().messageType)
export const rtcWebSocket = createMemo(() => rtcState().ws)
export const rtcConnectedPeers = createMemo(() => rtcState().connectedPeers)
export const rtcConnectInterval = createMemo(() => rtcState().connectInterval)
export const rtcTimeout = createMemo(() => rtcState().timeout)
25 changes: 0 additions & 25 deletions GUI/ETVR/src/store/api/websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@ import { createStore, produce } from 'solid-js/store'
import { RTCMessageType, RTCState } from '@src/static/types/enums'

export interface IWebSocket {
ws: WebSocket[]
pc?: RTCPeerConnection
dc?: RTCDataChannel
status: RTCState
messageType: RTCMessageType
camStream?: any
connectedPeers?: string[]
connectInterval?: NodeJS.Timeout
timeout?: number
}

export const defaultState: IWebSocket = {
ws: [],
status: RTCState.DISCONNECTED,
messageType: RTCMessageType.VIDEO_OFFER,
camStream: null,
connectedPeers: [],
connectInterval: undefined,
timeout: 250,
}
Expand All @@ -40,20 +36,6 @@ export const setRTCMessageType = (messageType: RTCMessageType) => {
}),
)
}
export const setRTCWebSocket = (ws: WebSocket) => {
setState(
produce((s) => {
s.ws.push(ws)
}),
)
}
export const setRemoveRTCWebSocket = (ws: WebSocket) => {
setState(
produce((s) => {
s.ws = s.ws.filter((w) => w !== ws)
}),
)
}
export const setConnectInterval = (interval: NodeJS.Timeout) => {
setState(
produce((s) => {
Expand All @@ -68,12 +50,5 @@ export const setRTCTimeout = (time: number) => {
}),
)
}
export const setWebsocketClients = (clients: WebSocket[]) => {
setState(
produce((s) => {
s.ws = clients
}),
)
}

export const rtcState = createMemo(() => state)
10 changes: 10 additions & 0 deletions GUI/ETVR/src/store/camera/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface ICamera {
type: CameraType
address: string
activeCameraSection: string
ws?: WebSocket
}

const tempCameraComponents: ICamera[] = [
Expand Down Expand Up @@ -108,4 +109,13 @@ export const setSelectedCamera = (camera: ICamera) => {
)
}

export const setCameraSocket = (camera: ICamera, ws: WebSocket) => {
setState(
produce((s) => {
s.cameras = s.cameras.filter((c: { address: string }) => c.address !== camera.address)
s.cameras.push({ ...camera, ws })
}),
)
}

export const cameraState = createMemo(() => state)
8 changes: 8 additions & 0 deletions GUI/ETVR/src/store/camera/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ import { cameraState } from './camera'
export const cameras = createMemo(() => cameraState().cameras)
export const cameraAddresses = createMemo(() => cameraState().cameras.map(({ address }) => address))
export const cameraStatus = createMemo(() => cameraState().cameras.map(({ status }) => status))
export const selectedCamera = createMemo(() => cameraState().selectedCamera)
export const selectedCameraAddress = createMemo(() => cameraState().selectedCamera.address)
export const selectedCameraStatus = createMemo(() => cameraState().selectedCamera.status)
export const selectedCameraType = createMemo(() => cameraState().selectedCamera.type)
export const selectedCameraSection = createMemo(
() => cameraState().selectedCamera.activeCameraSection,
)
export const selectedCameraSocket = createMemo(() => cameraState().selectedCamera.ws)
98 changes: 52 additions & 46 deletions GUI/ETVR/src/utils/hooks/websocket/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// TODO: Switch to tauri websocket plugin - https://github.com/tauri-apps/tauri-plugin-websocket
import { RTCState } from '@src/static/types/enums'
import { rtcWebSocket, rtcTimeout, rtcConnectInterval } from '@store/api/selectors'
import { rtcTimeout, rtcConnectInterval } from '@store/api/selectors'
import { setRTCStatus, setConnectInterval, setRTCTimeout } from '@store/api/websocket'
//import { WebSocket } from 'tauri-plugin-websocket-api'

import { cameras } from '@store/camera/selectors'

const PORT = 7856
Expand All @@ -18,15 +16,15 @@ const sendToRTCServer = (msg: IWebRTCMessage) => {
console.error('[sendToRTCServer]: Message is null or undefined')
return
}
rtcWebSocket().forEach((element) => {
element.send(JSON.stringify(msg))
cameras().forEach((camera) => {
if (camera.ws) camera.ws.send(JSON.stringify(msg))
})
}

export const check = () => {
const ws = rtcWebSocket()
ws.forEach((element) => {
if (!element || element.readyState == WebSocket.CLOSED) {
const ws = cameras()
ws.forEach((camera) => {
if (!camera.ws || camera.ws.readyState == WebSocket.CLOSED) {
//check if websocket instance is closed, if so call `init` function.
setRTCStatus(RTCState.DISCONNECTED)
initWebSocket()
Expand All @@ -50,52 +48,60 @@ const generateWebsocketClients = () => {
*/
const initWebSocket = () => {
setRTCStatus(RTCState.CONNECTING)
rtcWebSocket().forEach((element) => {
element.onopen = () => {
setRTCTimeout(250) // reset timer to 250 on open of websocket connection
clearTimeout(rtcConnectInterval()) // clear Interval on open of websocket connection
cameras().forEach((camera) => {
if (camera.ws) {
camera.ws.onopen = () => {
setRTCTimeout(250) // reset timer to 250 on open of websocket connection
clearTimeout(rtcConnectInterval()) // clear Interval on open of websocket connection

setRTCStatus(RTCState.CONNECTED)
setInterval(() => {
sendToRTCServer({
msg: {
msg_type: 'heartbeat',
receiver: '',
sender: '',
msg: '',
},
})
}, 1000 * 10)
setRTCStatus(RTCState.CONNECTED)
setInterval(() => {
sendToRTCServer({
msg: {
msg_type: 'heartbeat',
receiver: '',
sender: '',
msg: '',
},
})
}, 1000 * 10)

console.log('[WebSocket Client]: Connection Opened')
console.log('[WebSocket Client]: Connection Opened')
}
}
})
//* TODO: Add notification to the user
rtcWebSocket().forEach((element) => {
element.onerror = (e) => {
setRTCStatus(RTCState.ERROR)
console.error('[WebSocket Client]: Socket encountered error: ', e, 'Closing socket')
rtcWebSocket().forEach((element) => {
if (!element || element.readyState != WebSocket.CONNECTING) {
if (element.bufferedAmount <= 0) element.close()
}
})
cameras().forEach((camera) => {
if (camera.ws) {
camera.ws.onerror = (e) => {
setRTCStatus(RTCState.ERROR)
console.error('[WebSocket Client]: Socket encountered error: ', e, 'Closing socket')
cameras().forEach((camera) => {
if (camera.ws) {
if (camera.ws.readyState != WebSocket.CONNECTING) {
if (camera.ws.bufferedAmount <= 0) camera.ws.close()
}
}
})
}
}
})
//* TODO: Add notification to the user
rtcWebSocket().forEach((element) => {
element.onclose = (e) => {
console.log(
`[WebSocket Client]: Socket is closed. Reconnect will be attempted in ${Math.min(
10000 / 1000,
((rtcTimeout() as number) + (rtcTimeout() as number)) / 1000,
)} second.`,
e.reason,
)
//increment retry interval
setRTCTimeout((rtcTimeout() as number) + (rtcTimeout() as number))
//call check function after timeout
setConnectInterval(setTimeout(check, Math.min(10000, rtcTimeout() as number)))
cameras().forEach((camera) => {
if (camera.ws) {
camera.ws.onclose = (e) => {
console.log(
`[WebSocket Client]: Socket is closed. Reconnect will be attempted in ${Math.min(
10000 / 1000,
((rtcTimeout() as number) + (rtcTimeout() as number)) / 1000,
)} second.`,
e.reason,
)
//increment retry interval
setRTCTimeout((rtcTimeout() as number) + (rtcTimeout() as number))
//call check function after timeout
setConnectInterval(setTimeout(check, Math.min(10000, rtcTimeout() as number)))
}
}
})
}
Expand Down

0 comments on commit d5f70a6

Please sign in to comment.