Last active
December 16, 2015 00:49
-
-
Save jacobbubu/5350844 to your computer and use it in GitHub Desktop.
Alternative WebSocket implementation for ActionHero using
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RFC Web Socket Server | |
# You must have the web server enabled as well | |
configData.rfcWebSocket = | |
mount: "/ws" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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