npm install socket.io
与Node http server联合使用
Server(app.js)
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client(index.html)
<script src="/socket.io/socket.io.js">script>
<script>
var socket = io('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
script>
Socket.io
允许发出与接收自定义事件。除了connect
、message
、disconnect
,也可以发出自定义事件:
Server
// note, io() will create a http server for you
var io = require('socket.io')(80);
io.on('connection', function (socket) {
io.emit('this', { will: 'be received by everyone'});
socket.on('private message', function (from, msg) {
console.log('I received a private message by ', from, ' saying ', msg);
});
socket.on('disconnect', function () {
io.emit('user disconnected');
});
});
如果对于某个特定的应用程序,能够自己控制所有发出的消息与事件,那么默认/命名空间起作用。如果想要利用第三方代码或者生成代码与他人共享,socket.io
提供socket命名空间的方式。
这会带来复用单一连接的好处。socket.io没有使用两个WebSocket
连接,仅仅使用一个。
Server(app.js)
var io = require('socket.io')(80);
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.emit('a message', {
that: 'only'
, '/chat': 'will get'
});
chat.emit('a message', {
everyone: 'in'
, '/chat': 'will get'
});
});
var news = io
.of('/news')
.on('connection', function (socket) {
socket.emit('item', { news: 'item' });
});
Client(index.html)
<script>
var chat = io.connect('http://localhost/chat')
, news = io.connect('http://localhost/news');
chat.on('connect', function () {
chat.emit('hi!');
});
news.on('news', function () {
news.emit('woot');
});
script>
有时候,某些消息可以丢弃。假如有一个应用,展示关键词bieber实时微博数。
如果某个客户不准备接收消息(因为网速太慢或者其他问题,或者因为通过长时间轮询以连接,而目前正处于请求-响应中间阶段),如果没有收到所有有关bieber的微博,应用不会有事。
那种场合的话,也许想要将那些消息作为volatile消息发送。
Server
var io = require('socket.io')(80);
io.on('connection', function (socket) {
var tweets = setInterval(function () {
getBieberTweet(function (tweet) {
socket.volatile.emit('bieber tweet', tweet);
});
}, 100);
socket.on('disconnect', function () {
clearInterval(tweets);
});
});
有时候,当客户确认消息接收后,也许想获取回调。
为此,只传递一个函数作为.send
或者.emit
最后一个参数即可。另外,当使用.emit
时,确认得由自己做,这表示也可以这样传递数据:
Server(app.js)
var io = require('socket.io')(80);
io.on('connection', function (socket) {
socket.on('ferret', function (name, fn) {
fn('woot');
});
});
Client(index.html)
<script>
var socket = io(); // TIP: io() with no args does auto-discovery
socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
socket.emit('ferret', 'tobi', function (data) {
console.log(data); // data will be 'woot'
});
});
script>
为广播,只要在emit
与send
方法调用上增加一个broadcast
标志即可。广播表示给每个人发送一条消息,除了发起的那个socket。
Server
var io = require('socket.io')(80);
io.on('connection', function (socket) {
socket.broadcast.emit('user connected');
});
如果仅仅想要WebSocket语义,也可以那样做。只要利用send
,并监听message
事件:
Server(app.js)
var io = require('socket.io')(80);
io.on('connection', function (socket) {
socket.on('message', function () { });
socket.on('disconnect', function () { });
});
Client(index.html)
<script>
var socket = io('http://localhost/');
socket.on('connect', function () {
socket.send('hi');
socket.on('message', function (msg) {
// my msg
});
});
script>