WebSocket以及socketIO的使用
简介
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。
html5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
原生socket
socket是在http基础上,对http进行升级,让连接用socket来完成。
一个典型的Websocket握手请求如下:
客户端请求
服务器回应
- Connection 必须设置 Upgrade,表示客户端希望连接升级。
- Upgrade 字段必须设置 Websocket,表示希望升级到 Websocket 协议。
- Sec-WebSocket-Key 是随机的字符串,服务器端会用这些数据来构造出一个 SHA-1 的信息摘要。把 “Sec-WebSocket-Key” 加上一个特殊字符串 “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算 SHA-1 摘要,之后进行 BASE-64 编码,将结果做为 “Sec-WebSocket-Accept” 头的值,返回给客户端。如此操作,可以尽量避免普通 HTTP 请求被误认为 Websocket 协议。
- Sec-WebSocket-Version 表示支持的 Websocket 版本。RFC6455 要求使用的版本是 13,之前草案的版本均应当弃用。
- Origin 字段是可选的,通常用来表示在浏览器中发起此 Websocket 连接所在的页面,类似于 Referer。但是,与 Referer 不同的是,Origin 只包含了协议和主机名称。
- 其他一些定义在 HTTP 协议中的字段,如 Cookie 等,也可以在 Websocket 中使用。
服务端
客户端
socket.io
原生socket较复杂,一般都通过框架来使用websocket,socket.io封装了websocket。
socket.io文档
安装:
简单使用
服务端
- 创建服务端IO对象 io = require('socket.io')(httpServer);
- 监视连接 io.on('connection',function(socket))
- 通过emit 、 on
- on(name,function(data){}) :绑定监听
- emit(name,data): 发送消息
客户端
- 引入客户端socket.io-client 库
- io(url) 连接服务端,得到socket对象(如果不指定url,将会连接默认主机地址)
- 通过emit,on实现通信
实现一个简易的聊天室
上面服务端如果使用socket.emit 实现的是服务端和客户端的一对一发送数据,那么如何将服务端收到的数据发送给其他用户,来实现聊天室效果呢?
这里就需要io.emit 发送数据给当前连接此服务器的所有用户。
服务端
客户端
接下来根据官网的方案进行优化
Here are some ideas to improve the application:
- Broadcast a message to connected users when someone connects or disconnects.
在服务端,通过io.on('connection') 监听用户连接。
socket.on('disconnect') 监听用户断开。
通过回调向客户端传递提示信息。 socket.id 可以用来独一无二的表示当前会话的客户端id
- Add support for nicknames.
- Don’t send the same message to the user that sent it himself. Instead, append the message directly as soon as he presses enter.
通过监听keydown事件,判定 event.which 的值是否为 13(enter的Unicode码是13)。如果是则emit 消息
- Add “{user} is typing” functionality.
通过监听input事件,来更新type信息
- Show who’s online.
- Add private messaging.
更多案例在官方仓库中查找
广州设计公司https://www.houdianzi.com 我的007办公资源网站https://www.wode007.com
NameSpaces、rooms
namespace允许用户去分配路径,这个的好处是可以减少TCP资源,同时进行通道隔离
默认的namespace是/ 通过 of 方法可以自定义namespace
对于每个namespace,都可以定义多个频道,也就是room,用户可以 join 和 left
有的时候需要将数据从一个进程发送到令一个进程,可以通过redis adapter

浙公网安备 33010602011771号