socket.io系列二 文档之概括


如何使用

安装:

npm install socket.io  

和node.js的http模块一起使用

服务端(app.js):

var app = require('http').createServer(handler);  
var io = require('socket.io')(app);  
var fs = require('fs');  
  
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);  
        });  
}  
app.listen(80);  
  
io.on('connection',function(socket){  
    socket.emit('news',{hello:'world'});  
    socket.on('my other event',function(data){  
        console.log(data);  
    })  
});  

客户端(index.html):

<\script src="/socket.io/socket.io.js">  
<\script>  
var socket = io('http://localhost');  
socket.on('news',function(data){  
  console.log(data);  
  socket.emit('my other event',{my:'data'});  
});  
 

使用express框架3/4:

服务端(app.js):

var app = require('express')();  
var server = require('http').Server(app);  
var io = require('socket.io')(server);  
  
server.listen(80);  
  
app.get('/',function(req,res){  
    res.sendfile(__dirname+'/index.html');  
});  
  
io.on('connection',function(socket){  
    socket.emit('news',{hello:'world'});  
    socket.on('my other event',function(data){  
        console.log(data);  
    })  
});  

客户端(index.html):

<\script src="/socket.io/socket.io.js">  
<\script>  
var socket = io('http://localhost');  
socket.on('news',function(data){  
  console.log(data);  
  socket.emit('my other event',{my:'data'});  
});  

使用express框架:(暂时不知道与上个真正意义的区别,并且此次测试服务端无法运行)

服务端(app.js):

var app = require('express').createServer();  
var io = require('socket.io')(app);  
  
app.listen(80);  
  
app.get('/', function (req, res) {  
  res.sendfile(__dirname + '/index.html');  
});  
  
io.on('connection', function (socket) {  
  socket.emit('news', { hello: 'world' });  
  socket.on('my other event', function (data) {  
    console.log(data);  
  });  
});  

客户端(index.html):

<\script src="/socket.io/socket.io.js">  
<\script>  
var socket = io('http://localhost');  
socket.on('news',function(data){  
  console.log(data);  
  socket.emit('my other event',{my:'data'});  
});  

发送和接收事件

socket.io允许你自定义发送和接收事件的名称,除了‘connect’,'message','disconnect':

//io.listen会创建一个http 服务器  
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.sockets.emit('user disconnected');  
        });  
    });  
})  
用命名空间来限制

如果在一个应用上你想控制所有的信息和事件,默认或者是命名空间都可以。如果你想借助第三方代码、分享代码给他人,socket.io提供了命名空间。

服务端(app.js):

//io.listen会创建一个http 服务器  
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'});  
});  

客服端(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');  
});  
  

发送易变的信息

有时一些确定的信息被发送,我们称你有一个实时显示基于关键词bieber的应用。

如果客户端没有准备去接收信息(因为网络延迟或者其他问题,或者他通过长连接已经连接了并且在一个轮询中),如果他没有接收到所有发出的信息,你应用时糟糕。

这种情况下,你应以把信息作为变动的信息发送出去。

服务端:

var io = require('socket.io').listen(80);  
  
io.sockets.on('connection', function (socket) {  
  var tweets = setInterval(function () {  
    getBieberTweet(function (tweet) {  
      socket.volatile.emit('bieber tweet', tweet);  
    });  
  }, 100);  
  
  socket.on('disconnect', function () {  
    clearInterval(tweets);  
  });  
});  

注意:这个地方官网上省略了 getBieberTweet()函数的声明。 根据参考http://runnable.com/UTlPMF-f2W1TAAAo/sending-volatile-messages-for-socket-io,getBieberTweet()函数如下:

function getBieberTweet(cb) {  
  cb('check out iambieber.com');  
}  

’index.js中的tweet为‘check out iambieber.com’。实际上getBieberTweet函数传递的参数为一个函数。也就是在index.js中,此方法可以省略。

发送和接收数据

有时,当客户端确认信息的接收时候能得到一个返回值。

为了做到这个,仅仅需要为send或者emit方法传递一个方法作为最后一个参数。当你使用emit时候,你同时传递数据:

服务端:

var io = require('socket.io').listen(80);  
  
io.sockets.on('connection', function (socket) {  
  socket.on('ferret', function (name, fn) {  
    fn('woot');  
  });  
});  

客户端:

  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'  
    });  
  });  

说明:输出的结果为:‘woot’, 服务端的代码中的name为‘tobi’。

广播消息

仅仅在emit和send方法前增加broadcast的标志。广播意味着消息将会发给任何人除了消息的发起者:

服务端:

var io = require('socket.io').listen(80);  
  
io.sockets.on('connection', function (socket) {  
  socket.broadcast.emit('user connected');  
});  

当做一个跨浏览器的websocket

如果你仅仅是需要实现websocket的基本功能即简单的发送消息,你可以这样做:

服务端:

var io = require('socket.io').listen(80);  
  
io.sockets.on('connection', function (socket) {  
  socket.on('message', function () { });  
  socket.on('disconnect', function () { });  
});  

客户端:

var socket = io('http://localhost/');  
  socket.on('connect', function () {  
    socket.send('hi');  
  
    socket.on('message', function (msg) {  
      // my msg  
    });  
  });  

如果你不关注重连的逻辑等等,你可以看下Engine.IO,它是用socket.io实现websocket的基本功能。

Written on December 13, 2014