Mercurial > hg > nodescore
comparison node_modules/socket.io/lib/client.js @ 77:cd921abc8887
added puredata trigger/OSC router
author | Rob Canning <rob@foo.net> |
---|---|
date | Tue, 15 Jul 2014 17:48:07 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
76:0ae87af84e2f | 77:cd921abc8887 |
---|---|
1 | |
2 /** | |
3 * Module dependencies. | |
4 */ | |
5 | |
6 var parser = require('socket.io-parser'); | |
7 var debug = require('debug')('socket.io:client'); | |
8 | |
9 /** | |
10 * Module exports. | |
11 */ | |
12 | |
13 module.exports = Client; | |
14 | |
15 /** | |
16 * Client constructor. | |
17 * | |
18 * @param {Server} server instance | |
19 * @param {Socket} connection | |
20 * @api private | |
21 */ | |
22 | |
23 function Client(server, conn){ | |
24 this.server = server; | |
25 this.conn = conn; | |
26 this.encoder = new parser.Encoder(); | |
27 this.decoder = new parser.Decoder(); | |
28 this.id = conn.id; | |
29 this.request = conn.request; | |
30 this.setup(); | |
31 this.sockets = []; | |
32 this.nsps = {}; | |
33 this.connectBuffer = []; | |
34 } | |
35 | |
36 /** | |
37 * Sets up event listeners. | |
38 * | |
39 * @api private | |
40 */ | |
41 | |
42 Client.prototype.setup = function(){ | |
43 this.onclose = this.onclose.bind(this); | |
44 this.ondata = this.ondata.bind(this); | |
45 this.ondecoded = this.ondecoded.bind(this); | |
46 this.decoder.on('decoded', this.ondecoded); | |
47 this.conn.on('data', this.ondata); | |
48 this.conn.on('close', this.onclose); | |
49 }; | |
50 | |
51 /** | |
52 * Connects a client to a namespace. | |
53 * | |
54 * @param {String} namespace name | |
55 * @api private | |
56 */ | |
57 | |
58 Client.prototype.connect = function(name){ | |
59 debug('connecting to namespace %s', name); | |
60 var nsp = this.server.of(name); | |
61 if ('/' != name && !this.nsps['/']) { | |
62 this.connectBuffer.push(name); | |
63 return; | |
64 } | |
65 | |
66 var self = this; | |
67 var socket = nsp.add(this, function(){ | |
68 self.sockets.push(socket); | |
69 self.nsps[nsp.name] = socket; | |
70 | |
71 if ('/' == nsp.name && self.connectBuffer) { | |
72 self.connectBuffer.forEach(self.connect, self); | |
73 delete self.connectBuffer; | |
74 } | |
75 }); | |
76 }; | |
77 | |
78 /** | |
79 * Disconnects from all namespaces and closes transport. | |
80 * | |
81 * @api private | |
82 */ | |
83 | |
84 Client.prototype.disconnect = function(){ | |
85 var socket; | |
86 // we don't use a for loop because the length of | |
87 // `sockets` changes upon each iteration | |
88 while (socket = this.sockets.shift()) { | |
89 socket.disconnect(); | |
90 } | |
91 this.close(); | |
92 }; | |
93 | |
94 /** | |
95 * Removes a socket. Called by each `Socket`. | |
96 * | |
97 * @api private | |
98 */ | |
99 | |
100 Client.prototype.remove = function(socket){ | |
101 var i = this.sockets.indexOf(socket); | |
102 if (~i) { | |
103 var nsp = this.sockets[i].nsp.name; | |
104 this.sockets.splice(i, 1); | |
105 delete this.nsps[nsp]; | |
106 } else { | |
107 debug('ignoring remove for %s', socket.id); | |
108 } | |
109 }; | |
110 | |
111 /** | |
112 * Closes the underlying connection. | |
113 * | |
114 * @api private | |
115 */ | |
116 | |
117 Client.prototype.close = function(){ | |
118 if ('open' == this.conn.readyState) { | |
119 debug('forcing transport close'); | |
120 this.conn.close(); | |
121 this.onclose('forced server close'); | |
122 } | |
123 }; | |
124 | |
125 /** | |
126 * Writes a packet to the transport. | |
127 * | |
128 * @param {Object} packet object | |
129 * @param {Boolean} whether packet is already encoded | |
130 * @param {Boolean} whether packet is volatile | |
131 * @api private | |
132 */ | |
133 | |
134 Client.prototype.packet = function(packet, preEncoded, volatile){ | |
135 var self = this; | |
136 | |
137 // this writes to the actual connection | |
138 function writeToEngine(encodedPackets) { | |
139 if (volatile && !self.conn.transport.writable) return; | |
140 for (var i = 0; i < encodedPackets.length; i++) { | |
141 self.conn.write(encodedPackets[i]); | |
142 } | |
143 } | |
144 | |
145 if ('open' == this.conn.readyState) { | |
146 debug('writing packet %j', packet); | |
147 if(!preEncoded) { // not broadcasting, need to encode | |
148 this.encoder.encode(packet, function (encodedPackets) { // encode, then write results to engine | |
149 writeToEngine(encodedPackets); | |
150 }); | |
151 } else { // a broadcast pre-encodes a packet | |
152 writeToEngine(packet); | |
153 } | |
154 } else { | |
155 debug('ignoring packet write %j', packet); | |
156 } | |
157 }; | |
158 | |
159 /** | |
160 * Called with incoming transport data. | |
161 * | |
162 * @api private | |
163 */ | |
164 | |
165 Client.prototype.ondata = function(data){ | |
166 this.decoder.add(data); | |
167 }; | |
168 | |
169 /** | |
170 * Called when parser fully decodes a packet. | |
171 * | |
172 * @api private | |
173 */ | |
174 | |
175 Client.prototype.ondecoded = function(packet) { | |
176 if (parser.CONNECT == packet.type) { | |
177 this.connect(packet.nsp); | |
178 } else { | |
179 var socket = this.nsps[packet.nsp]; | |
180 if (socket) { | |
181 socket.onpacket(packet); | |
182 } else { | |
183 debug('no socket for namespace %s', packet.nsp); | |
184 } | |
185 } | |
186 }; | |
187 | |
188 /** | |
189 * Called upon transport close. | |
190 * | |
191 * @param {String} reason | |
192 * @api private | |
193 */ | |
194 | |
195 Client.prototype.onclose = function(reason){ | |
196 debug('client close with reason %s', reason); | |
197 | |
198 // ignore a potential subsequent `close` event | |
199 this.destroy(); | |
200 | |
201 // `nsps` and `sockets` are cleaned up seamlessly | |
202 var socket; | |
203 while (socket = this.sockets.shift()) { | |
204 socket.onclose(reason); | |
205 } | |
206 | |
207 this.decoder.destroy(); // clean up decoder | |
208 }; | |
209 | |
210 /** | |
211 * Cleans up event listeners. | |
212 * | |
213 * @api private | |
214 */ | |
215 | |
216 Client.prototype.destroy = function(){ | |
217 this.conn.removeListener('data', this.ondata); | |
218 this.conn.removeListener('close', this.onclose); | |
219 this.decoder.removeListener('decoded', this.ondecoded); | |
220 }; |