首页 > IT职业 > IT图书 > 谈一谈我理解的socket
听说小米今天破发了。作为一个伪米粉,我还是比较谈定的,如果你的身边有一个人时长提醒你–苹果干到小米现在的位置需要50年,小米只需要10几年为什么;小米负债千亿人民币…等等谣言。说了这么多,小米依旧是小米,我依旧是哪个普普通通的屌丝程序员。
我在刚开始接触到项目的时候,看到一位同事为了保证本地状态和远端的状态,是用http进行轮询的,就像下面的代码一样:
{
//代码都是临时手写的 可能有不完善的见谅啊
let xmlhttp;
let isFishish = false;
let time = setInterval(()=>{
if(isFishish){
clearInterval(time)
}else{
getHttpRequest();
}
},3000)
function getHttpRequest(){
xmlhttp=null;
if(window.XMLHttpRequest)
{
xmlhttp=new XMLHttpRequest();
}else if (window.ActiveXObject)
{
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xmlhttp!=null)
{
xmlhttp.onreadystatechange=state_Change;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
else
{
alert("Your browser does not support XMLHTTP.");
}
}
function state_Change(){
if (xmlhttp.readyState==4)
{
if (xmlhttp.status==200)
{// 200 = OK
// ...our code here...
} else {
alert("Problem retrieving XML data");
}
}
}
}
这种轮询的方式有好有坏,能够初步的达到用户的需求,但是用户的数据改变却又不能即使的反馈给用户。算了就这样说好像没什么可塑性,就直接用一个生活小实例来描述吧。
从上面的例子上面就可以看出socket其实是可以,由服务端发起主动想客户端发送数据的。
前面说了这么多大体都提及了socket,但是具体的socket是什么?有什么优点?基本都介绍的模棱两可。现在来系统的介绍一下
关于socket的使用,我是直接用最基础的源码来写的,虽然最后知道了js里面有一个常用的库,但是想想呢?既然是写文章就直接用最基础的东西更能说明问题。
{
initWebSocket(){ //初始化weosocket
//ws地址
const wsuri = process.env.WS_API + "/websocket/threadsocket";
this.websock = new WebSocket(wsuri);
this.websock.onmessage = this.websocketonmessage
this.websock.onerror = this.websocketerror
this.websock.onopen = this.websocketonopen
this.websock.onclose = this.websocketclose
},
websocketonmessage(e){ //数据接收
const redata = JSON.parse(e.data);
console.log(redata.value);
},
websocketsend(data){//数据发送
this.websock.send(data);
},
websocketclose(e){ //关闭
console.log("connection closed (" + e.code + ")");
}
}
当然,我在这里使用的是vue,这套代码,自己的项目也在使用,是可以使用的。我在这里呢?主要来谈一下websocket的四个方法:
CONNECTING:值为0,表示正在连接。
OPEN:值为1,表示连接成功,可以通信了。
CLOSING:值为2,表示连接正在关闭。
CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
websock.addEventListener('open', function (event) {
// dosomethings...
});
当然,我在开发的时候遇到很常见的一个小问题,那就是socket容易断开。我最后这一块钱就想由断线重连谈起。
我在这里首先来介绍一下前面提到的一个回调onclose,这个如果存在连接中断的情况会调用该回调,告知客户端。首先看一下参数:

由上面的图解知道,close会有三个参数:code、reason、wasClean
| 状态码 | 名称 | 描述 |
|---|---|---|
0–999 | 保留段, 未使用. | |
1000 | CLOSE_NORMAL | 正常关闭; 无论为何目的而创建, 该链接都已成功完成任务. |
1001 | CLOSE_GOING_AWAY | 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开. |
1002 | CLOSE_PROTOCOL_ERROR | 由于协议错误而中断连接. |
1003 | CLOSE_UNSUPPORTED | 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据). |
1004 |
保留. | |
1005 | CLOSE_NO_STATUS |
保留. |
1006 | CLOSE_ABNORMAL |
保留. |
1007 | Unsupported Data | 由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据). |
1008 | Policy Violation | 由于收到不符合约定的数据而断开连接. 这是一个通用状态码, 用于不适合使用 1003 和 1009 状态码的场景. |
1009 | CLOSE_TOO_LARGE | 由于收到过大的数据帧而断开连接. |
1010 | Missing Extension | 客户端期望服务器商定一个或多个拓展, 但服务器没有处理, 因此客户端断开连接. |
1011 | Internal Error | 客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接. |
1012 | Service Restart | 服务器由于重启而断开连接. [Ref] |
1013 | Try Again Later | 服务器由于临时原因断开连接, 如服务器过载因此断开一部分客户端连接. [Ref] |
1014 | 由 WebSocket 标准保留以便未来使用. | |
1015 | TLS Handshake |
保留. |
1016–1999
| 由 WebSocket 标准保留以便未来使用. | |
2000–2999
| 由 WebSocket 拓展保留使用. | |
3000–3999
| 可以由库或框架使用. | |
4000–4999
| 可以由应用使用. |
DOMString用以表示服务器关闭连接的原因. 这是由服务器和子协议决定的.由上面的基础我们就可以在onclose回调里面做重连代码,我是这样写的
{
onclose(e){
if(!Object,is(e.code,1000)){
if(!e.wasClean) {
this.websock.close()
}
setTimeout(()=>{
initWebSocket();
},4000)
}
}
}
我这样写呢?暂时也没有发现什么错误,但是也不一定是全正确的。如果诸位看官在使用的时候有任何瑕疵请立即告诉我,我如果在使用中有任何不舒服的,我也会及时更新的。谢谢呢,您咧!!
最近老是9点半左右下班,大清早旁边的工地又不停的在吵,搅的人无神无主、五雷轰顶…哇啊啊啊,算了 或许这就是生命吧。反正一切的一切都是在炫耀自己懒罢了。最近呢?也准备和大学室友写一个项目,其中包含前端、后端、Android端。如果有看官希望一起开发、或者有兴趣的话,请联系我。大家一起边开发边学习边成长。好了,午时已到,准备睡觉,嗯 洗澡去了
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2899/viewspace-2813033/ ,如需转载,请注明出处,否则将追究法律责任。