WebSocket 长连接实现
2019-03-22 本文已影响0人
hunter97
由于工作需要,近期需要做一个即时通讯的功能,所以就单独去了解了一下WebSocket的相关知识,学习、使用一下WebSocket。
什么是WebSocket
WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。
为什么传统的HTTP协议不能做到WebSocket实现的功能?
这是因为HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。
其实在之前有两个替代方案,不过都不能完全满足需求。一个是轮询,一个是comet。简单理解,轮询就是通过js设置一个定时器不断查询接口,但是这样做会造成一个问题,定时器频率太慢相当于延时会很长,频率太快又会给服务器带来很大的压力;而comet可以理解为一次请求如果没有超过预定时间或者没有返回数据,就会一直保持链接状态,在服务器挂起一个线程,这就代表着也要消耗服务器资源,而且,一个HTTP连接在长时间没有数据传输的情况下,链路上的任何一个网关都可能关闭这个连接,而网关是我们不可控的,这就要求Comet连接必须定期发一些ping数据表示连接“正常工作”。
所以综上WebSocket是目前实现实时通讯的最优方案。
一、WebSocket基础
- WebSocket 属性
属性 | 描述 |
---|---|
Socket.readyState | 只读属性 readyState 表示连接状态,可以是以下值:0 - 表示连接尚未建立;1 - 表示连接已建立,可以进行通信;2 - 表示连接正在进行关闭;3 - 表示连接已经关闭或者连接不能打开。 |
Socket.bufferedAmount | 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 |
- WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | Socket.onopen | 连接建立时触发 |
message | Socket.onmessage | 客户端接收服务端数据时触发 |
error | Socket.onerror | 通信发生错误时触发 |
close | Socket.onclose | 连接关闭时触发 |
- WebSocket 方法
方法 | 描述 |
---|---|
Socket.send() | 使用连接发送数据 |
Socket.close() | 关闭连接 |
二、代码示例
// 判断浏览器是否支持WebSocket
var is_support = ("WebSocket" in window);
if (is_support) {
// 打开一个 web socket
var ws = new WebSocket("ws://服务地址");
// Web Socket 已连接上
ws.onopen = function() {
// 使用 send() 方法向服务器发送数据
ws.send(数据);
console.log("数据发送中...");
};
// 接受服务器数据
ws.onmessage = function(e) {
var received_msg = e.data;
console.log("数据已接收...");
};
// 连接关闭
ws.onclose = function() {
// 关闭 websocket
console.log("连接已关闭...");
};
} else {
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
三、相关注意事项
- 正常ajax访问服务器地址可以通过
http
或https
,而WebSocket访问服务器地址要通过ws
。 - 可以在通过在地址后面加一个
?
加其他要传递的参数。类似于get的请求方式。如:ws://127.0.0.1:5000?id=213
- 通过
send
方法向服务器发送数据时,我们只能传递字符串,所以在发送数据前如果数据结构比较复杂就需要JSON.stringify()
方法将参数转为字符串,同时也需要用JSON.parse()
方法将服务端发送的数据解析出来。
参考文献:
廖雪峰-WebSocket
菜鸟教程 HTML5 WebSocket
人生总是会有不期而遇的温暖和生生不息的希望。前提是足够努力,才不会错过美丽的风景和动人的事。