当前栏目
WebSocket 入门:简易聊天室
大家好,我是前端西瓜哥,今天我们用 WebSocket 来实现一个简单的聊天室。
WebSocket 是一个应用层协议,有点类似 HTTP。但和 HTTP 不一样的是,它支持真正的全双工,即不仅客户端可以主动发消息给服务端,服务端也可以主动发消息给客户端。
尤其是后者,让我们不用再基于 HTTP 长轮询或短轮询的低效方式来实现服务端通知。相比 HTTP,WebSocket 的服务端推送更轻量,并能减少服务端的压力。
服务端
nodejs 并没有提供原生的 WebSocket 模块。如果要实现,需要基于 net 模块,根据 WebSocket 标准去做实现。
因为实现很复杂,所以西瓜哥我选择直接用第三库 ws。
类似 nodejs 原生的 http 等模块,ws 库支持 WebSocket 的服务端或客户端, 提供偏底层的 API。
我们先实现服务端代码:
每当一个客户端进行了 websocket 连接,都会触发 wsServer 的 connection 事件,然后拿到一个 ws 对象。
这个 ws 对象代表了某个客户端和服务端的连接,我们可以通过它来接收对应客户端的消息,并让服务端对指定客户端进行主动消息推送。
新创建的 ws 对象会在建立连接时保存到 wsServer.clients 集合下,并在关闭连接后移除。所以我们可以利用这个 wsServer.clients 来进行广播,实现聊天室功能。
客户端
客户端使用原生的 WebSocket 对象,来和服务端进行 WebSocket 连接。
效果
简易聊天室
改为使用 Socket.IO
ws 库是偏底层的实现,比较简单。
另一个库 Socket.IO 的底层使用了 ws,并做功能上的增强,提供更多的能力。
相比 ws,Socket.IO 能够做到:
- 如果浏览器不支持 WebSocket,回退为 HTTP 长轮询方案来模拟 WebSocket( WebSocket 于 2011 年完成 RFC,已经很久了,目前来说主流浏览器都已经支持 WebSocket 了,还不支持 WebSocket 的浏览器是屑)。
- 使用心跳包机制实现了自动重连。
- 包缓存。断连时发送数据,会将数据保存下来,等重新连接后再发送。
- 自定义事件支持。
- 广播。
相比自己去一个个实现,使用流行的轮子可能是更好的选择。
我们将前面的功能用 Socket.IO 实现一下。
服务端:
需要特别注意的是,Socket.IO 的 v3.x 版本开始,默认不允许跨域,需要在配置显式设置为允许跨域。
客户端:
Socket.IO 优点是实现了生产环境需要的底层非业务能力,让我们能更心无旁骛地去编写业务代码。
缺点是丢失了灵活性。因为做了定制化,所以需要配套使用 Socket.IO 的客户端和服务端库的包,某种意义脱离了网络协议标准。在出现跨语言(比如前端是 JS,后端是 Java)的场景时,需要提供对应的语言的 Socket.IO 实现。
demo
demo 已经放到 github 上了,使用方法在 README.md 中有说明。
https://github.com/F-star/websocket-chat-demo
结尾
本文演示了 WebSocket 简易的聊天室功能是如何实现的,希望对你有所帮助。
相关文章
- JDK中内嵌JS引擎介绍及使用
- 49195,npm最后的疯狂?盘点10款最有前途JavaScript构建工具
- 译文:5个增强Node.js应用程序增强功能
- 4个例子,吃透 JavaScript 实现的二叉搜索树 BST
- Vue中使用XML和JSON格式互转插件
- JDK中Jshell简单使用(JDK9版本以上或者JDK9版本)
- shiro中的JSP标签支持
- Java技术点-json转对象,对象转json
- SpringBoot+SpringDataJpa @Query之 JPQL使用书写模板(模糊查询and条件查询)
- Spring Boot中的Freemarker模版引擎引用css和js的正确姿势
- Node.js解压版的环境配置及相关常用命令
- JSP学习笔记(6)—— 自定义MVC框架
- JSP学习笔记(5)——Servlet、监听器、过滤器、MVC模式介绍
- Jsp学习笔记(4)——分页查询
- APIJSON简单使用
- JSP学习笔记(3)——JSTL 标签库
- JSP学习笔记(1)——Jsp指令、动作元素和内置对象
- JavaScript ES6 Promise对象
- Web前端——JavaScript扩展补充
- Web前端——表单提交和Js添加选项