Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 144 lines (119 sloc) 4.259 kb
cf820c5 Marek Add a license block to source files
majek authored
1 # ***** BEGIN LICENSE BLOCK *****
2 # Copyright (c) 2011-2012 VMware, Inc.
3 #
4 # For the license see COPYING.
5 # ***** END LICENSE BLOCK *****
6
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
7 FayeWebsocket = require('faye-websocket')
8
69d1e7f Marek Initial commit
majek authored
9 utils = require('./utils')
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
10 transport = require('./transport')
69d1e7f Marek Initial commit
majek authored
11
b74e0cc Marek Simplifying transports, everything is now a polling transport.
majek authored
12
69d1e7f Marek Initial commit
majek authored
13 exports.app =
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
14 _websocket_check: (req, connection, head) ->
1c4bed6 Bryce Kahle Use faye for websocket request checks. No need to duplicate them.
brycekahle authored
15 if not FayeWebsocket.isWebSocket(req)
69d1e7f Marek Initial commit
majek authored
16 throw {
04b3351 Marek All websocket errors should end with 400.
majek authored
17 status: 400
1c4bed6 Bryce Kahle Use faye for websocket request checks. No need to duplicate them.
brycekahle authored
18 message: 'Not a valid websocket request'
69d1e7f Marek Initial commit
majek authored
19 }
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
20
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
21 sockjs_websocket: (req, connection, head) ->
22 @_websocket_check(req, connection, head)
dfd84b8 David Glasser Allow specifying options to Faye constructor
glasser authored
23 ws = new FayeWebsocket(req, connection, head, null,
24 @options.faye_server_options)
378c795 Marek Use faye 0.4, update code to use ws.onopen faye callback.
majek authored
25 ws.onopen = =>
26 # websockets possess no session_id
27 transport.registerNoSession(req, @,
28 new WebSocketReceiver(ws, connection))
69d1e7f Marek Initial commit
majek authored
29 return true
ab2c7aa Marek support for websockets hybi-10, ie: new firefox and development chrome
majek authored
30
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
31 raw_websocket: (req, connection, head) ->
32 @_websocket_check(req, connection, head)
33 ver = req.headers['sec-websocket-version'] or ''
d9ed0e5 Marek Cosmetic
majek authored
34 if ['8', '13'].indexOf(ver) is -1
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
35 throw {
36 status: 400
37 message: 'Only supported WebSocket protocol is RFC 6455.'
38 }
dfd84b8 David Glasser Allow specifying options to Faye constructor
glasser authored
39 ws = new FayeWebsocket(req, connection, head, null,
40 @options.faye_server_options)
378c795 Marek Use faye 0.4, update code to use ws.onopen faye callback.
majek authored
41 ws.onopen = =>
42 new RawWebsocketSessionReceiver(req, connection, @, ws)
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
43 return true
44
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
45
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
46 class WebSocketReceiver extends transport.GenericReceiver
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
47 protocol: "websocket"
48
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
49 constructor: (@ws, @connection) ->
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
50 try
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
51 @connection.setKeepAlive(true, 5000)
52 @connection.setNoDelay(true)
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
53 catch x
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
54 @ws.addEventListener('message', (m) => @didMessage(m.data))
55 super @connection
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
56
57 setUp: ->
58 super
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
59 @ws.addEventListener('close', @thingy_end_cb)
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
60
61 tearDown: ->
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
62 @ws.removeEventListener('close', @thingy_end_cb)
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
63 super
64
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
65 didMessage: (payload) ->
66 if @ws and @session and payload.length > 0
67 try
68 message = JSON.parse(payload)
69 catch x
204b18f Bryce Kahle Fix websocket bad json tests
brycekahle authored
70 return @didClose(1002, 'Broken framing.')
7010788 Marek Fix #58 - don't emit an array - always a string
majek authored
71 if payload[0] is '['
72 for msg in message
73 @session.didMessage(msg)
74 else
75 @session.didMessage(message)
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
76
77 doSendFrame: (payload) ->
78 if @ws
79 try
80 @ws.send(payload)
81 return true
b28bd76 Marek #93 - cosmetic - unify "catch" statement
majek authored
82 catch x
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
83 return false
84
204b18f Bryce Kahle Fix websocket bad json tests
brycekahle authored
85 didClose: (status=1000, reason="Normal closure") ->
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
86 super
87 try
204b18f Bryce Kahle Fix websocket bad json tests
brycekahle authored
88 @ws.close(status, reason, false)
75144c1 Marek Fix #36 - Use faye-websocket websocket server implementation
majek authored
89 catch x
90 @ws = null
283decf Marek #36 - Emergency fix for being incompetent. (via @shripadk)
majek authored
91 @connection = null
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
92
93
94
95 Transport = transport.Transport
96
97 # Inheritance only for decorateConnection.
98 class RawWebsocketSessionReceiver extends transport.Session
99 constructor: (req, conn, server, @ws) ->
100 @prefix = server.options.prefix
101 @readyState = Transport.OPEN
98a3c9d David Glasser Correct version of 73c3e3.
glasser authored
102 @recv = {connection: conn, protocol: "websocket-raw"}
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
103
104 @connection = new transport.SockJSConnection(@)
105 @decorateConnection(req)
106 server.emit('connection', @connection)
107 @_end_cb = => @didClose()
108 @ws.addEventListener('close', @_end_cb)
109 @_message_cb = (m) => @didMessage(m)
110 @ws.addEventListener('message', @_message_cb)
111
112 didMessage: (m) ->
113 if @readyState is Transport.OPEN
114 @connection.emit('data', m.data)
115 return
116
117 send: (payload) ->
118 if @readyState isnt Transport.OPEN
119 return false
120 @ws.send(payload)
121 return true
122
123 close: (status=1000, reason="Normal closure") ->
124 if @readyState isnt Transport.OPEN
125 return false
126 @readyState = Transport.CLOSING
d94a2e6 Marek #99 - Never require client to send back an acknowledgment for ws closure
majek authored
127 @ws.close(status, reason, false)
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
128 return true
129
130 didClose: ->
f29fb5b Marek Fix #75 - raw websockets never emitted close event
majek authored
131 if not @ws
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
132 return
133 @ws.removeEventListener('message', @_message_cb)
134 @ws.removeEventListener('close', @_end_cb)
135 try
d94a2e6 Marek #99 - Never require client to send back an acknowledgment for ws closure
majek authored
136 @ws.close(1000, "Normal closure", false)
e203719 Marek sockjs/sockjs-protocol#35 - Support raw websocket /websocket interface
majek authored
137 catch x
138 @ws = null
f29fb5b Marek Fix #75 - raw websockets never emitted close event
majek authored
139
140 @readyState = Transport.CLOSED
141 @connection.emit('end')
142 @connection.emit('close')
143 @connection = null
Something went wrong with that request. Please try again.