socket.io模块

  • 官方文档(英文)

  • 使用文档(中文)

  • Socket.IOws相似,但是却比ws开发效率更高的一个WebSocket 模块,socket.io包括了客户端的js服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用,有以下特点:

    • 易用性:socket.io封装了服务端和客户端,使用起来非常简单方便。
    • 跨平台:socket.io支持跨平台,这就意味着你有了更多的选择,可以在自己喜欢的平台下开发实时应用。
    • 自适应:它会自动根据浏览器从WebSocketAJAX长轮询Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5
    • 支持自定义监听事件: 我们之前在ws模块中,只能通过ws.on('message',function)的方式来监听里面的switch分支来实现群聊和私聊功能等,但是使用socket.io就能实现自定义监听,如前端:io.on('群聊',function),服务端:emit('群聊')就能实现监听一个群聊消息
    • 自动重新启动功能的实现: socket.io模块下的客户端会在我们服务器重启后自动的向服务器连接,就不会像我们使用ws模块的时候,服务器自动重启过后客户端需要重新刷新

基本使用

安装socket.io

npm install socket.io

引入以及搭建socket服务器

//引入以及搭建服务器
const io = require('socket.io')();//快速搭建
// or
const Server = require('socket.io');
const io = new Server();

基于express框架的使用(服务端)

/*
从这段代码中可以看出,相较于ws模块重新开辟一个服务器,socket.io模块是结合使用
http模块来创建服务器后,将后面使用的socket服务器与它绑定在一起来实现的
*/

//由这部分代码可以看出,socket.io创建的服务器是与http服务器公用一个端口的
const app = require('express')();//创建服务器
const server = require('http').createServer(app);//创建服务器
const io = require('socket.io')(server);//创建socket服务器并与http服务器绑定在一起
io.on('connection', () => { /* … */ });//设置监听事件('connection可以自定义')
server.listen(3000);//公用一个端口

// 启动服务器
server.listen(3000,()=>{
console.log('服务器已启动,3000端口正在监听....');
})

socket模块的引入(客户端),浏览器前端内置ws模块因此不需要引入

客户端的使用文档

<!-- 引入socket.io.min.js (前面执行了安装socket.io后我们可以直接在node_modules中引入)-->
<script src="../node_modules/socket.io/client-dist/socket.io.min.js"></script>
<!-- 或者使用官方文档推荐的引入方式 -->
<script src="./js/socket.io.js"></script>

socket.io模块的基本使用

//前端页面
//直接使用不绑定端口
const socket = io();//默认会连接你创建的http服务器端口,上面的3000端口

//指定端口(或者携带参数)
const socket = io(`ws://localhost:3000?token=${localStorage.getItem('token')}`);
  • 前后端消息的转发与接收(形式与vue的事件总线非常的相似)
//后端收发消息
//发送消息使用.emit()[使用.emit('事件名','消息')发送消息]
socket.emit('消息事件','消息')//这与vue的事件总线非常的相似(前端用on来监听msg事件即可)
//接收消息使用.on
socket.on('消息事件',(msg)=>{})

//前端收发消息
//前端页面发送消息使用.emit()[使用.emit('事件名','消息')发送消息]
socket.emit('消息事件','消息')//这与vue的事件总线非常的相似(前端用on来监听msg事件即可)
//前端页面接收消息[使用socket.on('事件名',(data)=>{})来接受消息]
socket.on('消息事件',(msg)=>{
console.log(msg);//输出接收到对应事件的消息
})

/*
前后端都是用.emit()来发送消息,使用.on来接受消息
*/

io模块服务端提供的一些特殊api,与ws模块的区别

  • 获取所有当前连接到这台socket服务器的客户端
//ws模块
wss.clients()//调用这个接口就能获取到所有当前链接到这台服务器的客户端
//返回的数据是一个set结构

//io模块
io.sockets.sockets
//返回的数据是一个map结构
  • 对所有当前连接到这台socket服务器的客户端进行操作
//ws模块
wss.clients()//调用这个方法就能对所有当前链接到这台服务器的客户端进行操作

//io模块
io.sockets.emit() || io.sockets.on()
//io模块提供一个.sockets方法可以向所有的客户端进行操作

//io模块
socket.boardcast.emit()//对出自己外的所有客户端操作[英文意思:广播功能]

之所以说io模块相较于ws模块更加的自由,是因为io模块在服务端只提供两个固定的消息事件,那就是connection(当有客户端连接到这台服务器的时候)以及disconnection(当有客户端从这台服务器中断联的时候)

//当有客户端链接到这台服务器的时候
io.on('connection',(socket,req)=>{})

//当有客户端从这台服务器中断开连接的时候
io.on('disconnect',(socket,req)=>{})

给特定的客户端发送消息

  • 因为io模块不像ws模块存在.clients这个属性能过获取所有当前连接到这台服务器的客户端,所以只能使用io.sockets.sockets(里面存放着所有连接到这台服务器上的客户端),然后通过将其转化为数组再通过特定的条件来遍历获取特定客户端,切记因为io.sockets.sockets是以map结构来存储数据的,因此你将它转化为数组后应该是一个二维的数组,因此我们需要注意调用:item[1]