WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此 API,您可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。
# 零、官方链接
- 哔哩哔哩教程链接
- MDN: WebSocket
- NPM: nodejs-websocket
- Socket.io
# 一、客户端
# 1.1 构造函数
WebSocket(url[, protocols\])
返回一个 WebSocket
对象
const socket = new WebSocket('ws:// ...')
# 1.2 方法
WebSocket.send(msg)
对要传输的数据进行排队
WebSocket.close()
关闭当前链接
# 1.3 事件
利用 addEventListener
可以对 socket
实例对象进行事件监听
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
2
3
4
5
6
7
8
9
10
11
12
Close
当一个 WebSocket
连接被关闭时触发。
也可以通过 onclose
属性来设置
error
当一个 WebSocket
连接因错误而关闭时触发,例如无法发送数据时。
也可以通过 onerror
属性来设置
message
当通过 WebSocket
收到数据时触发。
也可以通过 onmessage
属性来设置
open
当一个 WebSocket
连接成功时触发
也可以通过 onopen
属性来设置
# 二、基础服务端
# 2.1 创建服务
利用 nodejs-websocket
这个库来构建一个基础的 websocket 服务
yarn add nodejs-websocket -S
安装完包之后
import ws from 'nodejs-websocket'
const PORT = 3000
const server = ws.createServer(connect => {
console.log(`有用户链接上来之后触发打印`)
})
server.listen(PORT, ()=>{
console.log(`服务启动时打印`)
})
2
3
4
5
6
7
8
9
10
11
# 2.2 注册处理数据
利用回调对象中的 text
事件监听用户传入的数据
var ws = require("nodejs-websocket")
// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
console.log("New connection")
conn.on("text", function (str) {
console.log("Received "+str)
conn.sendText(str.toUpperCase()+"!!!")
})
conn.on("close", function (code, reason) {
console.log("Connection closed")
})
conn.on('error', (err)=>{
console.log(err)
})
}).listen(8001)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
当用户链接之后可以通过监听 close
事件监听到用户断开服务
如果用户异常退出,则会触发 error
事件,比如用户在不断开的情况下直接关闭网页
这种情况如果 不做处理,会让服务端报错停止进程,一般情况下会在监听出加上 on error
处理错误异常
# 2.3 广播消息
每一个用户建立连接后都会生成一个新的 connect
,每一个对应的是当前用户
如果在聊天室情况下我们需要给所有用户广播信息
需要利用到 server.connentions
这个数组,这里面存了所有正在建立链接的用户 connect
集合
这样我们就可以定义一个广播函数,用于给所有建立链接的用户发信息
...
const broadcast = (msg)=>{
server.connections.forEach(item=> {
item.send(msg)
})
}
...
2
3
4
5
6
7
8
9
# 三、Socket.io
如果使用原生的
websocket
进行开发,会比较麻烦,比如支持的事件太少,发送的数据智能是字符串格式的,提供的 api 也很少,类似于广播这种通用方法需要自己封装
# 3.1 基本使用
服务端使用前需要先安装包 socket.io
npm install socket.io
如果是网页端引用可以直接引入在线资源
<script src="/socket.io/socket.io.js"></script>
Socket.IO 背后的主要思想是,您可以发送和接收想要的任何事件
为了向所有人发送事件,Socket.IO 为我们提供了io.emit()
方法。
io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' });
// This will emit the event to all connected sockets
2
如果您想向除某个发射套接字之外的所有人发送消息,即广播数据,有broadcast
从该套接字发射的标志:
io.on('connection', (socket) => {
socket.broadcast.emit('hi');
});
// 常用广播方式
io.on('connection', (socket) => {
socket.on('chat message', (msg) => {
io.emit('chat message', msg);
});
});
2
3
4
5
6
7
8
9
10
在客户端,当我们捕获一个chat message
事件时,我们会将其包含在页面中。现在总的客户端 JavaScript 代码相当于:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function(e) {
e.preventDefault();
if (input.value) {
socket.emit('chat message', input.value);
input.value = '';
}
});
socket.on('chat message', function(msg) {
var item = document.createElement('li');
item.textContent = msg;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 3.2 集成于 Express
先安装 express
npm install express@4
在创建 express
实例的时候将 socket.io
挂载
# app.js
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
io.on('connection', (socket) => {
console.log('a user connected');
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20