websocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket是一种双向通信协议,它建立在TCP之上,同HTTP一样通过TCP来传输数据,但与HTTP最大不同的是:

  1. WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UserAgent都能主动的向对象发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的简单模拟Socket的协议。

  2. WebSocket需要通过握手连接,类似TCP也需要客户端和服务端进行握手连接,连接成功后才能相互通信。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

利用websocket,可以在没有请求的情况下,由前端向后台或者后台向前端主动进行数据传送,可以实现数据更新后的及时通信

socket.io

后台代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var express = require('express');
var app = express();
var http = require('http');
//创建一个服务器
var server = http.createServer(app);
//监听端口
var port = normalizePort(process.env.PORT || '3000');
server.listen(port);

app.set('views', path.join(__dirname, 'views'));

//服务器端引入socket.io
var io = require('socket.io').listen(server);
io.on('connection', function(socket){
socket.on('message', function () { });
socket.on('disconnect', function(){...});
});

前端代码

1
2
3
4
5
6
7
8
9
//客户端引入socket
var socket = io();
socket.on('connect', function () {
socket.send('hi');

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

原理

  • 服务器保存好所有的 Client->Server 的 Socket 连接,
  • Client A 发送消息给 Client B 的实质是:Client A -> Server -> Client B。
  • 即 Client A 发送类似 {from:’Client A’, to:’Client B’, body: ‘hello’} 的数据给 Server。
  • Server 接收数据根据 to值找到 Client B 的 Socket 连接并将消息转发给 Client B。

使用

  • 使用socket.io,其前后端句法是一致的。
  • 即通过socket.emit() 来激发一个事件;
  • 通过socket.on() 来监听和处理对应事件;
  • 这两个事件通过传递的参数进行通信。

基本语法

  • 客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // send to current request socket client
    // 发送一个请求的当前请求的socket客户端
    socket.emit('message', "this is a test");
    // sending to all clients except sender
    // 广播消息,不包括当前的发送者
    socket.broadcast.emit('message', "this is a test");
    // sending to all clients, include sender
    // 发送消息给所有客户端,包括发送者
    io.sockets.emit('hi', 'everyone');
    io.emit('hi', 'everyone'); // 写的简单点:
  • 房间内发送

    1
    2
    3
    4
    5
    6
    // sending to all clients in 'room1' room except sender
    // 给房间room1的所有客户端发送消息,不包括发送者
    socket.broadcast.to('room1').emit('message', 'hello');
    // sending to all clients in 'room1' room(channel), include sender
    // 给房间room1的所有客户端发送消息,包括发送者
    io.sockets.in('room1').emit('message', 'hello')
  • 指定发送给某个用户

    1
    2
    3
    // sending to individual socketid
    // 给单个用户socketId发送消息
    io.sockets.socket(socketId).emit('message', 'for your eyes only');