乐趣区

前端培训中级阶段25Web-Socket-网络编程20191114期

前端最基础的就是 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]);

  1. code 表示错误码。默认为1005。CloseEvent
  2. 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);// 保持心跳

总结

  1. socket 需要保存心跳,一般是 ping、pong 逻辑。
  2. 超时时间是可以人为设置的,所以心跳时间也是可以选择的。(我的是 20s,所以心跳是 10s。公司之前做的 5m)。
  3. socket 如果断线要注意重连。因为都会落到 close 里面,所以我们可以直接在 close 里面重连。

    1. 部分情况要注意 重连频率 、以及 重连次数 的策略。
  4. 发送和接受只能是字符串,所以要JSON.stringify()

微信公众号:前端 linong

参考文献

  1. 前端培训目录、前端培训规划、前端培训计划
  2. WebSockets
退出移动版