meshblu-server-websocket
Version:
Websocket Protocol Adapter for Meshblu
107 lines (90 loc) • 4.35 kB
text/coffeescript
_ = require 'lodash'
debug = require('debug')('meshblu-server-websocket:websocket-handler')
PooledJobManager = require './pooled-job-manager'
MeshbluWebsocket = require 'meshblu-websocket'
AuthenticateHandler = require './handlers/authenticate-handler'
UpdateAsHandler = require './handlers/update-as-handler'
WhoamiHandler = require './handlers/whoami-handler'
SendMessageHandler = require './handlers/send-message-handler'
class WebsocketHandler
constructor: ({,,,}) ->
= new PooledJobManager {, }
=
authenticate: AuthenticateHandler
identity:
message: SendMessageHandler
subscriptionlist:
updateas: UpdateAsHandler
whoami: WhoamiHandler
initialize: =>
.on 'message',
.on 'close',
handlerHandler: (handlerClass) =>
(data) =>
requestQueue = 'request'
responseQueue = 'response'
handler = new handlerClass {, , , requestQueue, responseQueue}
handler.do data, (error, type, response) =>
return error.message, [type, data], 500 if error?
type, response
# Event Listeners
onClose: =>
?.close()
onMessage: (event) =>
event.data, (error, type, data) =>
return error.message, event.data, 500 if error?
debug 'onMessage', error, type, data
return [type] data if [type]?
.send type, data if ?
# API endpoints
identity: (authData) =>
= _.pick authData, 'uuid', 'token'
request =
metadata:
auth:
jobType: 'Authenticate'
.do 'request', 'response', request, (error, response) =>
return 'error', status: 502, message: "Bad Gateway" if error?
return 'error', status: 504, message: 'Gateway Timeout' unless response?
{code,status} = response.metadata
return 'notReady', message: status, status: code unless code == 204
, (error) =>
return 'notReady', status: 502, message: 'Bad Gateway' if error?
'ready', message: status, status: code
subscriptionList: =>
request = metadata: {jobType: 'SubscriptionList'}
.do 'request', 'response', request, (error, jobResponse) =>
return 'error', status: 502, message: 'Bad Gateway', frame: ['subscriptionlist'] if error?
{metadata,rawData} = jobResponse
return 'error', status: metadata.code, message: metadata.status if metadata.code != 200
'subscriptionlist', JSON.parse(rawData)
# Helpers
connectUpstream: (authData, callback) =>
options = _.extend {}, authData,
= new MeshbluWebsocket options
.on 'whoami', (data) => 'whoami', data
.on 'device', (data) => 'device', data
.on 'devices', (data) => 'devices', data
.on 'message', (data) => 'message', data
.on 'mydevices', (data) => 'mydevices', data
.on 'registered', (data) => 'registered', data
.on 'updated', (data) => 'updated', data
.on 'unregistered', (data) => 'unregistered', data
.on 'subscribe', (data) => 'subscribe', data
.on 'unsubscribe', (data) => 'unsubscribe', data
.on 'error', (error) =>
delete
'error', message: error.message, code: 502
.close()
.connect callback
parseFrame: (frame, callback) =>
try frame = JSON.parse frame
return callback null, frame... if _.isArray(frame) && frame.length
callback new Error 'invalid frame, must be in the form of [type, data]'
sendFrame: (type, data) =>
debug 'sendFrame', type, data
frame = [type, data]
.send JSON.stringify frame
sendError: (message, frame, code) =>
'error', message: message, frame: frame, status: code
module.exports = WebsocketHandler