import { recognizerLogger as logger } from '../../configuration/LoggerConfig'
import * as RecognizerContext from '../../model/RecognizerContext'
function infinitePing (websocket) {
const websocketRef = websocket
websocketRef.pingLostCount++
if (websocketRef.pingLostCount > websocketRef.maxPingLost) {
websocket.close(1000, 'PING_LOST')
} else if (websocketRef.readyState <= 1) {
setTimeout(() => {
if (websocketRef.readyState <= 1) {
websocketRef.send(JSON.stringify({ type: 'ping' }))
infinitePing(websocketRef)
}
}, websocketRef.pingDelay)
}
}
/**
* Attach all socket attributes helping managing server connexion
* @param {WebSocket} websocket Current WebSocket
* @param {RecognizerContext} recognizerContext
*/
function addWebsocketAttributes (websocket, recognizerContext) {
const websocketConfiguration = recognizerContext.editor.configuration.recognitionParams.server.websocket
const socket = websocket
socket.start = new Date()
socket.autoReconnect = websocketConfiguration.autoReconnect
socket.maxRetryCount = websocketConfiguration.maxRetryCount
socket.pingEnabled = websocketConfiguration.pingEnabled
socket.pingDelay = websocketConfiguration.pingDelay
socket.maxPingLost = websocketConfiguration.maxPingLostCount
socket.pingLostCount = 0
socket.recognizerContext = recognizerContext
}
/**
* @param {RecognizerContext} recognizerContext Recognizer context
* @return {WebSocket} Opened WebSocket
*/
export function openWebSocket (recognizerContext) {
let socket
try {
// eslint-disable-next-line no-undef
socket = new WebSocket(recognizerContext.url)
addWebsocketAttributes(socket, recognizerContext)
if (socket.pingEnabled) {
infinitePing(socket)
}
socket.onopen = (e) => {
logger.trace('onOpen')
recognizerContext.websocketCallback(e)
}
socket.onclose = (e) => {
logger.trace('onClose', new Date() - socket.start)
recognizerContext.websocketCallback(e)
}
socket.onerror = (e) => {
logger.trace('onError')
recognizerContext.websocketCallback(e)
}
socket.onmessage = (e) => {
logger.trace('onMessage')
socket.pingLostCount = 0
const parsedMessage = JSON.parse(e.data)
if (parsedMessage.type !== 'pong') {
const callBackParam = {
type: e.type,
data: JSON.parse(e.data)
}
recognizerContext.websocketCallback(callBackParam)
}
}
} catch (error) {
recognizerContext.recognitionContexts[0].initPromise.reject(error)
logger.error('Unable to open websocket, Check the host and your connectivity')
}
return socket
}
/**
* Send data message
* @param {RecognizerContext} recognizerContext Current recognizer context
* @param {Object} message Data message
*/
export function send (recognizerContext, message) {
const recognizerContextRef = recognizerContext
recognizerContextRef.idle = false
const websocket = recognizerContextRef.websocket
if (websocket.readyState === 1) {
websocket.send(JSON.stringify(message))
logger.debug(`${message.type} message sent`, message)
} else {
throw RecognizerContext.LOST_CONNEXION_MESSAGE
}
}
/**
* Close the websocket
* @param {RecognizerContext} recognizerContext Current recognizer context
* @param {Number} code Exit code
* @param {String} reason Exit reason
*/
export function close (recognizerContext, code, reason) {
const websocket = recognizerContext.websocket
if (websocket && websocket.readyState < 2) {
websocket.close(code, reason)
}
}