SAKA'S BLOG

SocketIO官方文档-总览

最近因为要学习习一个即时通讯项目,需要用到socket通信,所以自己先学着写一下。服务器端做一个简单的中转站。截止我翻译的时候,最新版本是v1.7.3。

怎样使用

安装

1
$ npm install socket.io

在Node的http server上使用

服务器端(app.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
});
});

客户端(index.html)

1
2
3
4
5
6
7
8
9

<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>

在Express(3-4)中使用

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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)

1
2
3
4
5
6
7
8
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>

在Express2.x中使用

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
});
});

客户端

1
2
3
4
5
6
7
8
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>

发送和接收事件

Socket.IO允许你发射和接收自定义事件。除了connect,message,disconnect,你可以自定义自己的事件来发射。

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 注意io(<port>)会自动为你创建一个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.emit('user disconnected');
});
});

将socket.io控制在你自己的命名空间内

假如你在你的应用中控制着所有的信息和事件的发射,使用默认的命名空间即可。如果你引入了第三方库,或者你想要将你的代码分享给其他人,socket.io为你的socket创建了一个新的命名空间。

这样带来的好处是复用了同一个socket连接。两个连接,使用同一个socket.io。

服务端(app.js)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)

1
2
3
4
5
6
7
8
9
10
11
12
 <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>

发送不稳定信息

有时可以丢弃某些消息。 假设你有一个应用程序显示实时推文。

如果某个客户端没有准备好接收消息(由于网络速度慢或其他问题,或者因为通过长轮询连接,并且处于请求 - 响应周期的中间),如果没有收到所有的tweets 与bieber相关的消息,您的应用程序不会受到影响。

在这种情况下,您可能希望将这些消息作为可丢弃消息发送。

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
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的时候,回应会被你接收,这时候你可以再次发送消息。

服务端(app.js)

1
2
3
4
5
6
7
var io = require('socket.io')(80);

io.on('connection', function (socket) {
socket.on('ferret', function (name, fn) {
fn('woot');
});
});

客户端(index.html)

1
2
3
4
5
6
7
8
<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>

广播信息

你只需要在调用emitsend的时候添加一个标志即可。发送广播意味着给每一个连接上soket服务的人都发送这个消息。

服务器端

1
2
3
4
5
var io = require('socket.io')(80);

io.on('connection', function (socket) {
socket.broadcast.emit('user connected');
});

作为跨浏览器的webSocket使用

如果您只想要WebSocket,您也可以这样做。 简单地利用send和收听message事件:

服务端(app.js)

1
2
3
4
5
6
var io = require('socket.io')(80);

io.on('connection', function (socket) {
socket.on('message', function () { });
socket.on('disconnect', function () { });
});

客户端(index.html)

1
2
3
4
5
6
7
8
9
10
<script>
var socket = io('http://localhost/');
socket.on('connect', function () {
socket.send('hi');

socket.on('message', function (msg) {
// my msg
});
});
</script>

如果你不关心连接逻辑,可以考虑使用Engine.IO。他是socket.io使用的websocket层。