Skip to content

Instantly share code, notes, and snippets.

@jacobbubu
Last active December 16, 2015 00:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacobbubu/5350844 to your computer and use it in GitHub Desktop.
Save jacobbubu/5350844 to your computer and use it in GitHub Desktop.
Alternative WebSocket implementation for ActionHero using
# RFC Web Socket Server
# You must have the web server enabled as well
configData.rfcWebSocket =
mount: "/ws"
rfcWebSocket = (api, options, next) ->
type = 'rfcWebSocket'
attributes =
canChat: true
logConnections: true
logExits: false # will log it by ourself
sendWelcomeMessage: 50 # delay sending by 50ms
verbs: [
'quit'
'exit'
'roomChange'
'roomView'
'listenToRoom'
'silenceRoom'
'detailsView'
'say'
]
RawServer = require('websocket').server
server = new api.genericServer(type, options, attributes)
#
# REQUIRED METHODS
#
server._start = (next) ->
server.mount = api.configData.servers[type].mount ? '/ws'
httpServer = api.servers.servers['web'].server
server.rawServer = new RawServer
httpServer: httpServer
autoAcceptConnections: false
server.log 'rfcWebSocket bound to port ' +
api.configData.servers['web'].port +
' mounted at ' + server.mount, 'notice'
server.rawServer.on 'request', (request) ->
#connection = request.accept '', request.origin
#request.resourceURL
createClient request.accept(), request
next()
server._teardown = (next) ->
server.rawServer.shutDown()
next()
server.sendMessage = (connection, message, messageCount) ->
message.context ?= 'response'
messageCount ?= connection.messageCount
if message.context is 'response' and not message.messageCount?
message.messageCount = messageCount
utf8Data = JSON.stringify message
connection.rawConnection.sendUTF utf8Data, (err) ->
server.log 'rfcWebSocket send message error. ' + err, 'error', message if err?
#
# EVENTS
#
server.on 'connection', (connection) ->
connection.rawConnection.on 'close', (reasonCode, description) ->
server.log 'connection closed', 'info', {to: connection.remoteIP, reasonCode: reasonCode, description: description}
server.destroyConnection connection
return
connection.rawConnection.on 'error', (err) ->
server.log 'rfcWebSocket error: ' + err, 'error', err
try
connection.rawConnection.close()
server.destroyConnection connection
catch e
server.destroyConnection(connection)
connection.rawConnection.on 'message', (rawMessage) ->
if rawMessage.type isnt 'utf8'
server.log 'Unsupported message type(#{rawMessage.type})', 'error'
return
try
message = JSON.parse rawMessage.utf8Data
catch err
server.log "message parsing error(#{rawMessage.utf8Data}). " + err
, 'error'
, { rawMessage: rawMessage.utf8Data }
incommingMessage connection, message
return
server.on 'actionComplete', (connection, toRender, messageCount) ->
if connection.rawConnection.connected and toRender
connection.response.messageCount = messageCount
server.sendMessage connection, connection.response, messageCount
server.goodbye = (connection, reason) ->
try
connection.rawConnection.close()
server.destroyConnection connection
catch e
;
#
# HELPERS
#
createClient = (rawConnection, request) ->
server.buildConnection
remotePort: rawConnection.socket.remotePort
remoteAddress: request.remoteAddress
rawConnection: rawConnection
incommingMessage = (connection, message) ->
return unless connection?
verb = message.event ? ''
delete message.event
connection.messageCount++
messageCount = connection.messageCount
switch verb
when 'action'
connection.params = message.params ? {}
connection.error = null
connection.response = {}
server.processAction connection
when 'file'
server.processFile connection
else
words = (v for k, v of message)
connection.verbs verb, words, (err, data) ->
if err?
message =
status: err
context: 'response'
data: data
messageCount: messageCount
server.sendMessage connection, message
else
message =
status: "OK"
context: "response"
data: data
messageCount: messageCount
server.sendMessage connection, message
next server
# exports
exports.rfcWebSocket = rfcWebSocket
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment