前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。
这块内容是我早就想下手的,但是因为之前服务没跑起来。所以文章没写成。今天经过一下午,终于鼓捣好了 demo 地址
websocket
webSocket 可以帮助 浏览器 与服务器 完成 双向通信 。
在 webSocket 出现之前,我们想接收到服务端的数据需要使用一些特殊手段,比如 轮询 、 长连接。
构造函数
var protocol = 'wss'
if(location.protocol == "http:") protocol = 'ws'
ws = new WebSocket(protocol+"://ws.lilnong.top");
WebSocket(url[, protocols])
传入 webScoket 服务的 URL,即可建立连接。
属性与方法
名称 | 类型 | 描述 |
---|---|---|
url |
属性 | 当前连接的绝对路径 |
protocol |
属性 | 下属协议,对应构造函数第二个参数 |
readyState |
属性 | 当前的链接状态 |
bufferedAmount |
属性 | 当前连接的绝对路径 |
binaryType |
属性 | 数据类型:blob |
close() |
方法 | 关闭当前链接 |
send() |
方法 | 发送数据到服务端 |
readyState 状态码
常量 | 数值 | 描述 |
---|---|---|
WebSocket.CONNECTING |
0 |
正在连接中 |
WebSocket.OPEN |
1 |
已经连接并且可以双向通讯 |
WebSocket.CLOSING |
2 |
正在关闭中 |
WebSocket.CLOSED |
3 |
已关闭或者没有连接成功 |
WebSocket.send() 方法
WebSocket.send(String | ArrayBuffer | Blob | ArrayBufferView);
var protocol = 'wss'
if(location.protocol == "http:") protocol = 'ws'
wsTest = new WebSocket(protocol+"://ws.lilnong.top");
wsTest.onclose = ()=>console.log('onclose');
wsTest.onerror = ()=>console.log('onerror');
wsTest.onmessage = ()=>console.log('onmessage');
wsTest.onopen = ()=>console.log('onopen')
var blob = new Blob(['lilnong.top','水的一批'])
filereader = new FileReader()
filereader.readAsArrayBuffer(blob);
filereader.onload = function(){wsTest.send(filereader.result)
wsTest.send(new Int8Array(filereader.result))
}
wsTest.send(blob)
wsTest.send('lilnong.top 水的一批 1')
可以看到 blob 其实是发送失败了。一般来说我们还是发送 String 居多。
WebSocket.close() 方法
WebSocket.close([, reason]);
- code 表示错误码。默认为1005。CloseEvent
- reason 为错误码的描述。
回调函数
函数名称 | 触发时机 | 备注 |
---|---|---|
onclose |
当连接关闭后的回调函数 | 主动 close 或者被动 close 都会触发 |
onerror |
当连接失败后的回调函数 | 只有被动 close 会触发 |
onmessage |
当接收到服务端发送数据时的回调函数 | e.data 为服务端返回的信息 |
onopen |
当连接成功后的回调函数 | 之后就可以进行交互了 |
实现
node
依赖 ws = require('ws');
这个 websocket 模块。
我们可以把 connection
中的连接对象保存到全局的数组。这样我们就可以广播消息了。
在close
把连接对象移出数组。
var ws = require('ws');
var socketServer = ws.Server;
var wss = new socketServer({port: 8090});// 创建服务,监听 8090 端口
// 监听连接
wss.on('connection', function(ws){
// 推送消息
ws.send(JSON.stringify({type: 'start',time: Date.now()}))
// 接收浏览器端发送的消息
ws.on('message',function(message){console.log(JSON.parse(message))
})
// 监听连接断开
ws.on('close', function() {})
})
html
var initWs = function initWs(){
var protocol = 'wss'
if(location.protocol == "http:") protocol = 'ws'
ws = new WebSocket(protocol+"://ws.lilnong.top");
ws.onopen = function (e) {console.log('连接成功');}
// 收到消息处理
ws.onmessage = function (e) {console.log(e.data)
}
// 监听连接关闭情况
ws.onclose = function (e) {setTimeout(v=>initWs(), 2000);// 自动重连
console.log('连接关闭');
}
}
initWs();
setInterval(v=>{ws.send(JSON.stringify({type: 'ping'}));}, 10 * 1000);// 保持心跳
总结
- socket 需要保存心跳,一般是 ping、pong 逻辑。
- 超时时间是可以人为设置的,所以心跳时间也是可以选择的。(我的是 20s,所以心跳是 10s。公司之前做的 5m)。
-
socket 如果断线要注意重连。因为都会落到 close 里面,所以我们可以直接在 close 里面重连。
- 部分情况要注意 重连频率 、以及 重连次数 的策略。
- 发送和接受只能是字符串,所以要
JSON.stringify()
微信公众号:前端 linong
参考文献
- 前端培训目录、前端培训规划、前端培训计划
- WebSockets