rc-web@69
|
1 # Socket.IO
|
rc-web@69
|
2
|
rc-web@69
|
3 Socket.IO is a Node.JS project that makes WebSockets and realtime possible in
|
rc-web@69
|
4 all browsers. It also enhances WebSockets by providing built-in multiplexing,
|
rc-web@69
|
5 horizontal scalability, automatic JSON encoding/decoding, and more.
|
rc-web@69
|
6
|
rc-web@69
|
7 ## How to Install
|
rc-web@69
|
8
|
rc-web@69
|
9 ```bash
|
rc-web@69
|
10 npm install socket.io
|
rc-web@69
|
11 ```
|
rc-web@69
|
12
|
rc-web@69
|
13 ## How to use
|
rc-web@69
|
14
|
rc-web@69
|
15 First, require `socket.io`:
|
rc-web@69
|
16
|
rc-web@69
|
17 ```js
|
rc-web@69
|
18 var io = require('socket.io');
|
rc-web@69
|
19 ```
|
rc-web@69
|
20
|
rc-web@69
|
21 Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
|
rc-web@69
|
22 web framework:
|
rc-web@69
|
23
|
rc-web@69
|
24 #### Express 3.x
|
rc-web@69
|
25
|
rc-web@69
|
26 ```js
|
rc-web@69
|
27 var app = express()
|
rc-web@69
|
28 , server = require('http').createServer(app)
|
rc-web@69
|
29 , io = io.listen(server);
|
rc-web@69
|
30
|
rc-web@69
|
31 server.listen(80);
|
rc-web@69
|
32
|
rc-web@69
|
33 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
34 socket.emit('news', { hello: 'world' });
|
rc-web@69
|
35 socket.on('my other event', function (data) {
|
rc-web@69
|
36 console.log(data);
|
rc-web@69
|
37 });
|
rc-web@69
|
38 });
|
rc-web@69
|
39 ```
|
rc-web@69
|
40
|
rc-web@69
|
41 #### Express 2.x
|
rc-web@69
|
42
|
rc-web@69
|
43 ```js
|
rc-web@69
|
44 var app = express.createServer()
|
rc-web@69
|
45 , io = io.listen(app);
|
rc-web@69
|
46
|
rc-web@69
|
47 app.listen(80);
|
rc-web@69
|
48
|
rc-web@69
|
49 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
50 socket.emit('news', { hello: 'world' });
|
rc-web@69
|
51 socket.on('my other event', function (data) {
|
rc-web@69
|
52 console.log(data);
|
rc-web@69
|
53 });
|
rc-web@69
|
54 });
|
rc-web@69
|
55 ```
|
rc-web@69
|
56
|
rc-web@69
|
57 Finally, load it from the client side code:
|
rc-web@69
|
58
|
rc-web@69
|
59 ```html
|
rc-web@69
|
60 <script src="/socket.io/socket.io.js"></script>
|
rc-web@69
|
61 <script>
|
rc-web@69
|
62 var socket = io.connect('http://localhost');
|
rc-web@69
|
63 socket.on('news', function (data) {
|
rc-web@69
|
64 console.log(data);
|
rc-web@69
|
65 socket.emit('my other event', { my: 'data' });
|
rc-web@69
|
66 });
|
rc-web@69
|
67 </script>
|
rc-web@69
|
68 ```
|
rc-web@69
|
69
|
rc-web@69
|
70 For more thorough examples, look at the `examples/` directory.
|
rc-web@69
|
71
|
rc-web@69
|
72 ## Short recipes
|
rc-web@69
|
73
|
rc-web@69
|
74 ### Sending and receiving events.
|
rc-web@69
|
75
|
rc-web@69
|
76 Socket.IO allows you to emit and receive custom events.
|
rc-web@69
|
77 Besides `connect`, `message` and `disconnect`, you can emit custom events:
|
rc-web@69
|
78
|
rc-web@69
|
79 ```js
|
rc-web@69
|
80 // note, io.listen(<port>) will create a http server for you
|
rc-web@69
|
81 var io = require('socket.io').listen(80);
|
rc-web@69
|
82
|
rc-web@69
|
83 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
84 io.sockets.emit('this', { will: 'be received by everyone' });
|
rc-web@69
|
85
|
rc-web@69
|
86 socket.on('private message', function (from, msg) {
|
rc-web@69
|
87 console.log('I received a private message by ', from, ' saying ', msg);
|
rc-web@69
|
88 });
|
rc-web@69
|
89
|
rc-web@69
|
90 socket.on('disconnect', function () {
|
rc-web@69
|
91 io.sockets.emit('user disconnected');
|
rc-web@69
|
92 });
|
rc-web@69
|
93 });
|
rc-web@69
|
94 ```
|
rc-web@69
|
95
|
rc-web@69
|
96 ### Storing data associated to a client
|
rc-web@69
|
97
|
rc-web@69
|
98 Sometimes it's necessary to store data associated with a client that's
|
rc-web@69
|
99 necessary for the duration of the session.
|
rc-web@69
|
100
|
rc-web@69
|
101 #### Server side
|
rc-web@69
|
102
|
rc-web@69
|
103 ```js
|
rc-web@69
|
104 var io = require('socket.io').listen(80);
|
rc-web@69
|
105
|
rc-web@69
|
106 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
107 socket.on('set nickname', function (name) {
|
rc-web@69
|
108 socket.set('nickname', name, function () { socket.emit('ready'); });
|
rc-web@69
|
109 });
|
rc-web@69
|
110
|
rc-web@69
|
111 socket.on('msg', function () {
|
rc-web@69
|
112 socket.get('nickname', function (err, name) {
|
rc-web@69
|
113 console.log('Chat message by ', name);
|
rc-web@69
|
114 });
|
rc-web@69
|
115 });
|
rc-web@69
|
116 });
|
rc-web@69
|
117 ```
|
rc-web@69
|
118
|
rc-web@69
|
119 #### Client side
|
rc-web@69
|
120
|
rc-web@69
|
121 ```html
|
rc-web@69
|
122 <script>
|
rc-web@69
|
123 var socket = io.connect('http://localhost');
|
rc-web@69
|
124
|
rc-web@69
|
125 socket.on('connect', function () {
|
rc-web@69
|
126 socket.emit('set nickname', prompt('What is your nickname?'));
|
rc-web@69
|
127 socket.on('ready', function () {
|
rc-web@69
|
128 console.log('Connected !');
|
rc-web@69
|
129 socket.emit('msg', prompt('What is your message?'));
|
rc-web@69
|
130 });
|
rc-web@69
|
131 });
|
rc-web@69
|
132 </script>
|
rc-web@69
|
133 ```
|
rc-web@69
|
134
|
rc-web@69
|
135 ### Restricting yourself to a namespace
|
rc-web@69
|
136
|
rc-web@69
|
137 If you have control over all the messages and events emitted for a particular
|
rc-web@69
|
138 application, using the default `/` namespace works.
|
rc-web@69
|
139
|
rc-web@69
|
140 If you want to leverage 3rd-party code, or produce code to share with others,
|
rc-web@69
|
141 socket.io provides a way of namespacing a `socket`.
|
rc-web@69
|
142
|
rc-web@69
|
143 This has the benefit of `multiplexing` a single connection. Instead of
|
rc-web@69
|
144 socket.io using two `WebSocket` connections, it'll use one.
|
rc-web@69
|
145
|
rc-web@69
|
146 The following example defines a socket that listens on '/chat' and one for
|
rc-web@69
|
147 '/news':
|
rc-web@69
|
148
|
rc-web@69
|
149 #### Server side
|
rc-web@69
|
150
|
rc-web@69
|
151 ```js
|
rc-web@69
|
152 var io = require('socket.io').listen(80);
|
rc-web@69
|
153
|
rc-web@69
|
154 var chat = io
|
rc-web@69
|
155 .of('/chat')
|
rc-web@69
|
156 .on('connection', function (socket) {
|
rc-web@69
|
157 socket.emit('a message', { that: 'only', '/chat': 'will get' });
|
rc-web@69
|
158 chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
|
rc-web@69
|
159 });
|
rc-web@69
|
160
|
rc-web@69
|
161 var news = io
|
rc-web@69
|
162 .of('/news');
|
rc-web@69
|
163 .on('connection', function (socket) {
|
rc-web@69
|
164 socket.emit('item', { news: 'item' });
|
rc-web@69
|
165 });
|
rc-web@69
|
166 ```
|
rc-web@69
|
167
|
rc-web@69
|
168 #### Client side:
|
rc-web@69
|
169
|
rc-web@69
|
170 ```html
|
rc-web@69
|
171 <script>
|
rc-web@69
|
172 var chat = io.connect('http://localhost/chat')
|
rc-web@69
|
173 , news = io.connect('http://localhost/news');
|
rc-web@69
|
174
|
rc-web@69
|
175 chat.on('connect', function () {
|
rc-web@69
|
176 chat.emit('hi!');
|
rc-web@69
|
177 });
|
rc-web@69
|
178
|
rc-web@69
|
179 news.on('news', function () {
|
rc-web@69
|
180 news.emit('woot');
|
rc-web@69
|
181 });
|
rc-web@69
|
182 </script>
|
rc-web@69
|
183 ```
|
rc-web@69
|
184
|
rc-web@69
|
185 ### Sending volatile messages.
|
rc-web@69
|
186
|
rc-web@69
|
187 Sometimes certain messages can be dropped. Let's say you have an app that
|
rc-web@69
|
188 shows realtime tweets for the keyword `bieber`.
|
rc-web@69
|
189
|
rc-web@69
|
190 If a certain client is not ready to receive messages (because of network slowness
|
rc-web@69
|
191 or other issues, or because he's connected through long polling and is in the
|
rc-web@69
|
192 middle of a request-response cycle), if he doesn't receive ALL the tweets related
|
rc-web@69
|
193 to bieber your application won't suffer.
|
rc-web@69
|
194
|
rc-web@69
|
195 In that case, you might want to send those messages as volatile messages.
|
rc-web@69
|
196
|
rc-web@69
|
197 #### Server side
|
rc-web@69
|
198
|
rc-web@69
|
199 ```js
|
rc-web@69
|
200 var io = require('socket.io').listen(80);
|
rc-web@69
|
201
|
rc-web@69
|
202 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
203 var tweets = setInterval(function () {
|
rc-web@69
|
204 getBieberTweet(function (tweet) {
|
rc-web@69
|
205 socket.volatile.emit('bieber tweet', tweet);
|
rc-web@69
|
206 });
|
rc-web@69
|
207 }, 100);
|
rc-web@69
|
208
|
rc-web@69
|
209 socket.on('disconnect', function () {
|
rc-web@69
|
210 clearInterval(tweets);
|
rc-web@69
|
211 });
|
rc-web@69
|
212 });
|
rc-web@69
|
213 ```
|
rc-web@69
|
214
|
rc-web@69
|
215 #### Client side
|
rc-web@69
|
216
|
rc-web@69
|
217 In the client side, messages are received the same way whether they're volatile
|
rc-web@69
|
218 or not.
|
rc-web@69
|
219
|
rc-web@69
|
220 ### Getting acknowledgements
|
rc-web@69
|
221
|
rc-web@69
|
222 Sometimes, you might want to get a callback when the client confirmed the message
|
rc-web@69
|
223 reception.
|
rc-web@69
|
224
|
rc-web@69
|
225 To do this, simply pass a function as the last parameter of `.send` or `.emit`.
|
rc-web@69
|
226 What's more, when you use `.emit`, the acknowledgement is done by you, which
|
rc-web@69
|
227 means you can also pass data along:
|
rc-web@69
|
228
|
rc-web@69
|
229 #### Server side
|
rc-web@69
|
230
|
rc-web@69
|
231 ```js
|
rc-web@69
|
232 var io = require('socket.io').listen(80);
|
rc-web@69
|
233
|
rc-web@69
|
234 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
235 socket.on('ferret', function (name, fn) {
|
rc-web@69
|
236 fn('woot');
|
rc-web@69
|
237 });
|
rc-web@69
|
238 });
|
rc-web@69
|
239 ```
|
rc-web@69
|
240
|
rc-web@69
|
241 #### Client side
|
rc-web@69
|
242
|
rc-web@69
|
243 ```html
|
rc-web@69
|
244 <script>
|
rc-web@69
|
245 var socket = io.connect(); // TIP: .connect with no args does auto-discovery
|
rc-web@69
|
246 socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
|
rc-web@69
|
247 socket.emit('ferret', 'tobi', function (data) {
|
rc-web@69
|
248 console.log(data); // data will be 'woot'
|
rc-web@69
|
249 });
|
rc-web@69
|
250 });
|
rc-web@69
|
251 </script>
|
rc-web@69
|
252 ```
|
rc-web@69
|
253
|
rc-web@69
|
254 ### Broadcasting messages
|
rc-web@69
|
255
|
rc-web@69
|
256 To broadcast, simply add a `broadcast` flag to `emit` and `send` method calls.
|
rc-web@69
|
257 Broadcasting means sending a message to everyone else except for the socket
|
rc-web@69
|
258 that starts it.
|
rc-web@69
|
259
|
rc-web@69
|
260 #### Server side
|
rc-web@69
|
261
|
rc-web@69
|
262 ```js
|
rc-web@69
|
263 var io = require('socket.io').listen(80);
|
rc-web@69
|
264
|
rc-web@69
|
265 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
266 socket.broadcast.emit('user connected');
|
rc-web@69
|
267 socket.broadcast.json.send({ a: 'message' });
|
rc-web@69
|
268 });
|
rc-web@69
|
269 ```
|
rc-web@69
|
270
|
rc-web@69
|
271 ### Rooms
|
rc-web@69
|
272
|
rc-web@69
|
273 Sometimes you want to put certain sockets in the same room, so that it's easy
|
rc-web@69
|
274 to broadcast to all of them together.
|
rc-web@69
|
275
|
rc-web@69
|
276 Think of this as built-in channels for sockets. Sockets `join` and `leave`
|
rc-web@69
|
277 rooms in each socket.
|
rc-web@69
|
278
|
rc-web@69
|
279 #### Server side
|
rc-web@69
|
280
|
rc-web@69
|
281 ```js
|
rc-web@69
|
282 var io = require('socket.io').listen(80);
|
rc-web@69
|
283
|
rc-web@69
|
284 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
285 socket.join('justin bieber fans');
|
rc-web@69
|
286 socket.broadcast.to('justin bieber fans').emit('new fan');
|
rc-web@69
|
287 io.sockets.in('rammstein fans').emit('new non-fan');
|
rc-web@69
|
288 });
|
rc-web@69
|
289 ```
|
rc-web@69
|
290
|
rc-web@69
|
291 ### Using it just as a cross-browser WebSocket
|
rc-web@69
|
292
|
rc-web@69
|
293 If you just want the WebSocket semantics, you can do that too.
|
rc-web@69
|
294 Simply leverage `send` and listen on the `message` event:
|
rc-web@69
|
295
|
rc-web@69
|
296 #### Server side
|
rc-web@69
|
297
|
rc-web@69
|
298 ```js
|
rc-web@69
|
299 var io = require('socket.io').listen(80);
|
rc-web@69
|
300
|
rc-web@69
|
301 io.sockets.on('connection', function (socket) {
|
rc-web@69
|
302 socket.on('message', function () { });
|
rc-web@69
|
303 socket.on('disconnect', function () { });
|
rc-web@69
|
304 });
|
rc-web@69
|
305 ```
|
rc-web@69
|
306
|
rc-web@69
|
307 #### Client side
|
rc-web@69
|
308
|
rc-web@69
|
309 ```html
|
rc-web@69
|
310 <script>
|
rc-web@69
|
311 var socket = io.connect('http://localhost/');
|
rc-web@69
|
312 socket.on('connect', function () {
|
rc-web@69
|
313 socket.send('hi');
|
rc-web@69
|
314
|
rc-web@69
|
315 socket.on('message', function (msg) {
|
rc-web@69
|
316 // my msg
|
rc-web@69
|
317 });
|
rc-web@69
|
318 });
|
rc-web@69
|
319 </script>
|
rc-web@69
|
320 ```
|
rc-web@69
|
321
|
rc-web@69
|
322 ### Changing configuration
|
rc-web@69
|
323
|
rc-web@69
|
324 Configuration in socket.io is TJ-style:
|
rc-web@69
|
325
|
rc-web@69
|
326 #### Server side
|
rc-web@69
|
327
|
rc-web@69
|
328 ```js
|
rc-web@69
|
329 var io = require('socket.io').listen(80);
|
rc-web@69
|
330
|
rc-web@69
|
331 io.configure(function () {
|
rc-web@69
|
332 io.set('transports', ['websocket', 'flashsocket', 'xhr-polling']);
|
rc-web@69
|
333 });
|
rc-web@69
|
334
|
rc-web@69
|
335 io.configure('development', function () {
|
rc-web@69
|
336 io.set('transports', ['websocket', 'xhr-polling']);
|
rc-web@69
|
337 io.enable('log');
|
rc-web@69
|
338 });
|
rc-web@69
|
339 ```
|
rc-web@69
|
340
|
rc-web@69
|
341 ## License
|
rc-web@69
|
342
|
rc-web@69
|
343 (The MIT License)
|
rc-web@69
|
344
|
rc-web@69
|
345 Copyright (c) 2011 Guillermo Rauch <guillermo@learnboost.com>
|
rc-web@69
|
346
|
rc-web@69
|
347 Permission is hereby granted, free of charge, to any person obtaining
|
rc-web@69
|
348 a copy of this software and associated documentation files (the
|
rc-web@69
|
349 'Software'), to deal in the Software without restriction, including
|
rc-web@69
|
350 without limitation the rights to use, copy, modify, merge, publish,
|
rc-web@69
|
351 distribute, sublicense, and/or sell copies of the Software, and to
|
rc-web@69
|
352 permit persons to whom the Software is furnished to do so, subject to
|
rc-web@69
|
353 the following conditions:
|
rc-web@69
|
354
|
rc-web@69
|
355 The above copyright notice and this permission notice shall be
|
rc-web@69
|
356 included in all copies or substantial portions of the Software.
|
rc-web@69
|
357
|
rc-web@69
|
358 THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
rc-web@69
|
359 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
rc-web@69
|
360 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
rc-web@69
|
361 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
rc-web@69
|
362 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
rc-web@69
|
363 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
rc-web@69
|
364 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|