WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。在前端开发中,WebSocket 经常用来实现实时通信,例如聊天室、游戏等应用场景。Koa2 是一个 Node.js 的 Web 框架,它提供了基础的中间件架构,可以方便地实现 WebSocket 通信。在本文中,我们将介绍如何使用 Koa2 中的 WebSocket 实现聊天室应用。
WebSocket 基础
WebSocket 是一种基于 HTTP 协议的一种新的通信协议,它不同于 HTTP ,是一种双向的,浏览器和服务器可以同时发起通信的协议。WebSocket 的通讯机制和 TCP 协议非常相似,不过 WebSocket 能够跨过 HTTP 所有限制,而长连接则能够保持住这个通讯状态。
连接建立
在客户端使用 WebSocket 连接时,首先需要向服务器发起一个 HTTP 请求,请求头中包含如下信息:
GET /chat HTTP/1.1 Upgrade: websocket Connection: Upgrade Host: example.com Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Version: 13
- GET /chat 表示在服务器的 chat 路径下建立 WebSocket 连接
- Upgrade: websocket 表示客户端请求升级协议为 WebSocket
- Connection: Upgrade 表示连接类型为 Upgrade
- Host: example.com 表示请求的服务器地址
- Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== 表示客户端生成的随机字符串
- Sec-WebSocket-Version: 13 表示客户端请求的 WebSocket 版本
当服务器收到这个请求时,如果支持 WebSocket ,就会像客户端发送一条 HTTP 响应,响应头包含如下信息:
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
- HTTP/1.1 101 Switching Protocols 表示服务器切换协议
- Upgrade: websocket 表示升级协议为 WebSocket
- Connection: Upgrade 表示连接类型为 Upgrade
- Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= 表示服务器校验通过后生成的随机字符串
这个 HTTP 响应将会被浏览器和服务器作为 WebSocket 连接的起点。
通讯过程
建立好 WebSocket 连接后,浏览器和服务器之间就可以通过这个连接进行全双工通讯。在通讯过程中,浏览器向服务器发送的数据格式如下:
发送的数据格式为: 0x81(表示发送的是文本数据) 0x82(表示发送的是二进制数据,如果发送的是文本数据则是 0x81) 数据长度 掩码码值(如果客户端和服务端约定的是不掩码,则不需要添加这一部分) 数据内容
其中,掩码码值可以防止网络流量分析攻击。
在服务端接收到数据时,需要将数据解码才能得到原本的内容。在 Koa2 中,可以通过 koa-websocket 模块来实现 WebSocket 通讯。
使用 Koa2 中的 WebSocket 实现聊天室应用
Koa2 框架中提供了 koa-websocket 模块来实现 WebSocket 通讯,这个模块和 koa-router 模块类似,提供了基于 path 的路由分发。在本文中,我们将基于 koa-websocket 和 koa-router 来实现一个简单的聊天室应用。
安装 koa-websocket 和 koa-router
首先,需要在项目中安装 koa-websocket 和 koa-router 模块。使用以下命令进行安装:
npm i koa-websocket koa-router
创建聊天室路由
在项目的 app.js 文件中添加如下代码,创建聊天室路由:
-- -------------------- ---- ------- ----- --- - --------------- ----- --------- - ------------------------- ----- ------ - ---------------------- ----- --- - ------------- ------- ----- ------ - --- --------- ------------------------- --------------------------------- ------------------ ----- ----- -- - -- --- --- -----------------
在以上代码中,我们创建了一个 WebSocket 的 Koa2 应用,然后创建了一个路由转发的实例。通过 router.ws(path, handler)
方法来创建 WebSocket 请求处理器,其中 path
表示 WebSocket 的路径,handler
表示处理函数。在这里,我们使用 /chat
路径来处理聊天室请求。
实现聊天室逻辑
我们实现聊天室必须要处理两个事件:连接事件和消息事件。在连接事件中,需要将连接的 WebSocket 实例添加到连接池中,而在消息事件中,需要将消息广播给所有连接的客户端。
连接事件
处理连接事件的代码如下:
-- -------------------- ---- ------- ----- ----------- - --- ------ ------------------ ----- ----- -- - -- ---- --------- --------- ----- ------ - -------------- ------------------------ -- -------- ------------------ -- -- - --------------------------- --- ---
在以上代码中,我们使用了 Set
数据结构来存储所有连接的 WebSocket 实例。当一个连接断开时,需要将它从连接池中移除。
消息事件
处理消息事件的代码如下:
-- -------------------- ---- ------- ------------------ ----- ----- -- - -- ------ ----- ------ - -------------- -------------------- ----- -- - -- ------------- ------------------------ -- - -- ----- --- ------ -- --------------- --- -- - --------------- - --- --- ---
在以上代码中,我们使用 WebSocket 实例的 message
事件来处理消息。当接收到消息后,需要遍历连接池中的所有实例,然后将消息发送给除了发送者自己以外的所有客户端。
客户端实现
最后,我们在客户端上创建一个 WebSocket 对象来连接到该聊天室,并监听消息事件,将接收到的消息输出到控制台中。
const socket = new WebSocket('ws://localhost:3000/chat'); socket.onmessage = (event) => { console.log(event.data); };
到此,一个简单的聊天室应用就完成了。
总结
本文中介绍了如何使用 Koa2 中的 WebSocket 实现聊天室应用。在这个过程中,我们学习了 WebSocket 的基础知识,并使用 koa-websocket 和 koa-router 模块来实现了聊天室的路由转发,以及连接事件和消息事件的处理逻辑。这个应用虽然简单,但是对于理解 WebSocket 的应用场景和使用方法有很大的指导意义。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/645a09b6968c7c53b0c28c5f