什么是Socket.io
Socket.io是WebSocket的包装库,简化了WebSocket的使用。而WebSocket的作用就是在服务器与浏览器之间建立纯的Socket连接,这对实现聊天室等需要实时通讯的功能有很大的意义。
起手式
Socket.io提供客户端和服务器端两个版本。
Node服务器端
使用npm install socket.io
安装之。建立服务器脚本。Socket.io需要一个Server对象进行初始化,因此如果与Express框架结合使用,需按下列方式初始化:
const app = require('express')() // express app
const http = require('http').createServer(app) // 指定app当请求监听器
const sio = require('socket.io')(http) // 初始化服务器端Socket.io
// ...
http.listen(PORT)
浏览器端
从/node_modules/socket.io-client/dist
中复制socket.io.js
,即为客户端脚本。使用script标签引入即可。
<script src="./<your_own_path>/socket.io.js"></script>
如果你使用其他前端工程化的方案,则按你的方式引入该脚本。
然后建立Socket.io连接,取得Socket.io对象:
const sio = io(SERVER_URL)
基本使用
Socket.io全程采用异步式的基于消息的通讯方案。思想是使用emit
触发消息,使用相应的on
监听消息并处理。下面,我们通过一个简单的双向通讯的例子进行演示。
服务器端代码:
// server.js 服务器端
sio.on('connection', socket => { // connection事件表示新socket建立,回调参数是该socket
socket.emit('serverSay', dataToSend) // 服务器向该客户端发serverSay消息,附带数据dataToSend
socket.send(dataToSend) // 相当于emit('message', dataToSend)
socket.on('clientSay', data => { // 给该socket的clientSay事件绑回调函数,data的样式与客户端发过来的是一致的,因此你可以自信地使用ES6的解构赋值
// ... do something to data
})
})
客户端代码与服务器端大同小异:
// script.js 浏览器端
sio.on('connect', () => { // connect事件表示到服务器的socket建立,sio可用
sio.emit('clientSay', dataToSend) // 客户端向服务器端发clientSay消息,附带数据dataToSend
sio.on('serverSay', data => { // 处理服务器端发来的serverSay消息
// ... do something to data
})
})
广播
有时候,服务器端需要向当前所有连接的socket发送同样的消息,即进行广播。Socket.io提供了两种广播方式:
sio.emit
:对在sio上连接的所有socket发送消息socket.broadcast.emit
:对在sio上连接的、除了该socket自身以外的所有socket发送消息
关闭连接
客户端使用sio.disconnect()
即可断开该socket连接,此时在服务器端会触发该socket的disconnect
事件。
需要注意的是,客户端断开连接后并不会释放socket资源,而是准备用于下次连接的复用。这将导致无法再次触发服务器端的connection
事件。解决方法是使用sio = sio.connect()
进行重连。
命名空间
有时,我们需要在同一个服务器下挂载多个WebSocket服务,则可以通过命名空间来实现。
let namespaceA = sio.of(`/a`)
namespaceA.on('someEvent', callback)
这样,客户端可以与<SERVER_URL>/a
建立连接。此时只会执行该namespace下的消息处理逻辑。