rc-web@69: # Socket.IO
rc-web@69:
rc-web@69: Socket.IO is a Node.JS project that makes WebSockets and realtime possible in
rc-web@69: all browsers. It also enhances WebSockets by providing built-in multiplexing,
rc-web@69: horizontal scalability, automatic JSON encoding/decoding, and more.
rc-web@69:
rc-web@69: ## How to Install
rc-web@69:
rc-web@69: ```bash
rc-web@69: npm install socket.io
rc-web@69: ```
rc-web@69:
rc-web@69: ## How to use
rc-web@69:
rc-web@69: First, require `socket.io`:
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io');
rc-web@69: ```
rc-web@69:
rc-web@69: Next, attach it to a HTTP/HTTPS server. If you're using the fantastic `express`
rc-web@69: web framework:
rc-web@69:
rc-web@69: #### Express 3.x
rc-web@69:
rc-web@69: ```js
rc-web@69: var app = express()
rc-web@69: , server = require('http').createServer(app)
rc-web@69: , io = io.listen(server);
rc-web@69:
rc-web@69: server.listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.emit('news', { hello: 'world' });
rc-web@69: socket.on('my other event', function (data) {
rc-web@69: console.log(data);
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Express 2.x
rc-web@69:
rc-web@69: ```js
rc-web@69: var app = express.createServer()
rc-web@69: , io = io.listen(app);
rc-web@69:
rc-web@69: app.listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.emit('news', { hello: 'world' });
rc-web@69: socket.on('my other event', function (data) {
rc-web@69: console.log(data);
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: Finally, load it from the client side code:
rc-web@69:
rc-web@69: ```html
rc-web@69:
rc-web@69:
rc-web@69: ```
rc-web@69:
rc-web@69: For more thorough examples, look at the `examples/` directory.
rc-web@69:
rc-web@69: ## Short recipes
rc-web@69:
rc-web@69: ### Sending and receiving events.
rc-web@69:
rc-web@69: Socket.IO allows you to emit and receive custom events.
rc-web@69: Besides `connect`, `message` and `disconnect`, you can emit custom events:
rc-web@69:
rc-web@69: ```js
rc-web@69: // note, io.listen() will create a http server for you
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: io.sockets.emit('this', { will: 'be received by everyone' });
rc-web@69:
rc-web@69: socket.on('private message', function (from, msg) {
rc-web@69: console.log('I received a private message by ', from, ' saying ', msg);
rc-web@69: });
rc-web@69:
rc-web@69: socket.on('disconnect', function () {
rc-web@69: io.sockets.emit('user disconnected');
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: ### Storing data associated to a client
rc-web@69:
rc-web@69: Sometimes it's necessary to store data associated with a client that's
rc-web@69: necessary for the duration of the session.
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.on('set nickname', function (name) {
rc-web@69: socket.set('nickname', name, function () { socket.emit('ready'); });
rc-web@69: });
rc-web@69:
rc-web@69: socket.on('msg', function () {
rc-web@69: socket.get('nickname', function (err, name) {
rc-web@69: console.log('Chat message by ', name);
rc-web@69: });
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Client side
rc-web@69:
rc-web@69: ```html
rc-web@69:
rc-web@69: ```
rc-web@69:
rc-web@69: ### Restricting yourself to a namespace
rc-web@69:
rc-web@69: If you have control over all the messages and events emitted for a particular
rc-web@69: application, using the default `/` namespace works.
rc-web@69:
rc-web@69: If you want to leverage 3rd-party code, or produce code to share with others,
rc-web@69: socket.io provides a way of namespacing a `socket`.
rc-web@69:
rc-web@69: This has the benefit of `multiplexing` a single connection. Instead of
rc-web@69: socket.io using two `WebSocket` connections, it'll use one.
rc-web@69:
rc-web@69: The following example defines a socket that listens on '/chat' and one for
rc-web@69: '/news':
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: var chat = io
rc-web@69: .of('/chat')
rc-web@69: .on('connection', function (socket) {
rc-web@69: socket.emit('a message', { that: 'only', '/chat': 'will get' });
rc-web@69: chat.emit('a message', { everyone: 'in', '/chat': 'will get' });
rc-web@69: });
rc-web@69:
rc-web@69: var news = io
rc-web@69: .of('/news');
rc-web@69: .on('connection', function (socket) {
rc-web@69: socket.emit('item', { news: 'item' });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Client side:
rc-web@69:
rc-web@69: ```html
rc-web@69:
rc-web@69: ```
rc-web@69:
rc-web@69: ### Sending volatile messages.
rc-web@69:
rc-web@69: Sometimes certain messages can be dropped. Let's say you have an app that
rc-web@69: shows realtime tweets for the keyword `bieber`.
rc-web@69:
rc-web@69: If a certain client is not ready to receive messages (because of network slowness
rc-web@69: or other issues, or because he's connected through long polling and is in the
rc-web@69: middle of a request-response cycle), if he doesn't receive ALL the tweets related
rc-web@69: to bieber your application won't suffer.
rc-web@69:
rc-web@69: In that case, you might want to send those messages as volatile messages.
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: var tweets = setInterval(function () {
rc-web@69: getBieberTweet(function (tweet) {
rc-web@69: socket.volatile.emit('bieber tweet', tweet);
rc-web@69: });
rc-web@69: }, 100);
rc-web@69:
rc-web@69: socket.on('disconnect', function () {
rc-web@69: clearInterval(tweets);
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Client side
rc-web@69:
rc-web@69: In the client side, messages are received the same way whether they're volatile
rc-web@69: or not.
rc-web@69:
rc-web@69: ### Getting acknowledgements
rc-web@69:
rc-web@69: Sometimes, you might want to get a callback when the client confirmed the message
rc-web@69: reception.
rc-web@69:
rc-web@69: To do this, simply pass a function as the last parameter of `.send` or `.emit`.
rc-web@69: What's more, when you use `.emit`, the acknowledgement is done by you, which
rc-web@69: means you can also pass data along:
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.on('ferret', function (name, fn) {
rc-web@69: fn('woot');
rc-web@69: });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Client side
rc-web@69:
rc-web@69: ```html
rc-web@69:
rc-web@69: ```
rc-web@69:
rc-web@69: ### Broadcasting messages
rc-web@69:
rc-web@69: To broadcast, simply add a `broadcast` flag to `emit` and `send` method calls.
rc-web@69: Broadcasting means sending a message to everyone else except for the socket
rc-web@69: that starts it.
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.broadcast.emit('user connected');
rc-web@69: socket.broadcast.json.send({ a: 'message' });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: ### Rooms
rc-web@69:
rc-web@69: Sometimes you want to put certain sockets in the same room, so that it's easy
rc-web@69: to broadcast to all of them together.
rc-web@69:
rc-web@69: Think of this as built-in channels for sockets. Sockets `join` and `leave`
rc-web@69: rooms in each socket.
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.join('justin bieber fans');
rc-web@69: socket.broadcast.to('justin bieber fans').emit('new fan');
rc-web@69: io.sockets.in('rammstein fans').emit('new non-fan');
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: ### Using it just as a cross-browser WebSocket
rc-web@69:
rc-web@69: If you just want the WebSocket semantics, you can do that too.
rc-web@69: Simply leverage `send` and listen on the `message` event:
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.sockets.on('connection', function (socket) {
rc-web@69: socket.on('message', function () { });
rc-web@69: socket.on('disconnect', function () { });
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: #### Client side
rc-web@69:
rc-web@69: ```html
rc-web@69:
rc-web@69: ```
rc-web@69:
rc-web@69: ### Changing configuration
rc-web@69:
rc-web@69: Configuration in socket.io is TJ-style:
rc-web@69:
rc-web@69: #### Server side
rc-web@69:
rc-web@69: ```js
rc-web@69: var io = require('socket.io').listen(80);
rc-web@69:
rc-web@69: io.configure(function () {
rc-web@69: io.set('transports', ['websocket', 'flashsocket', 'xhr-polling']);
rc-web@69: });
rc-web@69:
rc-web@69: io.configure('development', function () {
rc-web@69: io.set('transports', ['websocket', 'xhr-polling']);
rc-web@69: io.enable('log');
rc-web@69: });
rc-web@69: ```
rc-web@69:
rc-web@69: ## License
rc-web@69:
rc-web@69: (The MIT License)
rc-web@69:
rc-web@69: Copyright (c) 2011 Guillermo Rauch <guillermo@learnboost.com>
rc-web@69:
rc-web@69: Permission is hereby granted, free of charge, to any person obtaining
rc-web@69: a copy of this software and associated documentation files (the
rc-web@69: 'Software'), to deal in the Software without restriction, including
rc-web@69: without limitation the rights to use, copy, modify, merge, publish,
rc-web@69: distribute, sublicense, and/or sell copies of the Software, and to
rc-web@69: permit persons to whom the Software is furnished to do so, subject to
rc-web@69: the following conditions:
rc-web@69:
rc-web@69: The above copyright notice and this permission notice shall be
rc-web@69: included in all copies or substantial portions of the Software.
rc-web@69:
rc-web@69: THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
rc-web@69: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
rc-web@69: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
rc-web@69: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
rc-web@69: CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
rc-web@69: TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
rc-web@69: SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.