原文链接 https://www.web-tinker.com/article/20310.html

WebSocket是很民主的,啥都要协商!建立连接时需要握手协议,连断开连接都需要双方共同完成!其实断开连接直接断开TCP连接就可以了,但是这有点暴力。文明点的方法是发个请求,让对方自己断开。客户端要主动断开就必须向服务器发送8这个操作码。
  首先是服务器主导断开的情况,最简单的方法是直接把TCP连接断开,这里就不演示了。由于这对客户端来说是个意外断开,WebSocket对象采取应急措施也触发close事件。咱是文明人,当然要做点有绅士风度的事情。于是咱不从服务器断开连接,而是向客户端发送个请求断开的操作码来请求客户端自己断开。
  其实就是个操作码为8的帧。但要注意的是数据部分比较特殊。当然如果嫌麻烦可以不传,不过要是不传就和前面的霸王硬上弓一样无节操了。数据部分的前两个字节是状态码,之后的部分是关闭连接原因的文本描述,这些东西可以传到客户端。
  (encodeDataFrame与decodeDataFrame函数见生成数据帧和解析数据帧)

//客户端程序
var ws=new WebSocket("ws://127.0.0.1:8000");
ws.onclose=function(e){console.log(e);ws.close(); //关闭TCP连接
};

========================================================

//服务器程序
var crypto=require('crypto');
var WS='258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
require('net').createServer(function(o){var key;o.on('data',function(e){if(!key){//握手key=e.toString().match(/Sec-WebSocket-Key: (.+)/)[1];key=crypto.createHash('sha1').update(key+WS).digest('base64');o.write('HTTP/1.1 101 Switching Protocols\r\n');o.write('Upgrade: websocket\r\n');o.write('Connection: Upgrade\r\n');o.write('Sec-WebSocket-Accept: '+key+'\r\n');o.write('\r\n');//构造断连请求的数据部分,前面留两字节存放状态码var buf=new Buffer('\0\0孩子,地球太危险了,快回火星去吧!');buf.writeUInt16BE(1000,0); //在头两个字节写入一个状态码//发送断连请求o.write(encodeDataFrame({FIN:1,Opcode:8,PayloadData:buf}));};});
}).listen(8000);

客户端会在onclose的参数中接收到一个这样的东西,状态码和结束原因描述分别在code和reason两个参数中。规范文档中规定了很多状态码的含义,不过这个目前不是强制性的,我就不列举了。见RFC6455#section-7.4。客户端在收到服务器的这个断连请求后应该调用close方法来关闭,否则连接会先入停滞状态等待客户端响应。
  服务器主导断开的情况就是这样。下面是客户端主导断开的情况。客户端先要调用close方法,这个操作会发送一个断连请求到服务器上,服务器收到这个请求后把TCP连接断开即可。但是服务器程序是自己写的,这个请求也需要自己解析。

//客户端程序
var ws=new WebSocket("ws://127.0.0.1:8000");
ws.onopen=function(){ws.close(); //发起断连请求
};
ws.onclose=function(e){console.log(e);
};
//服务端程序序
var crypto=require('crypto');
var WS='258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
require('net').createServer(function(o){var key;o.on('data',function(e){if(!key){//握手key=e.toString().match(/Sec-WebSocket-Key: (.+)/)[1];key=crypto.createHash('sha1').update(key+WS).digest('base64');o.write('HTTP/1.1 101 Switching Protocols\r\n');o.write('Upgrade: websocket\r\n');o.write('Connection: Upgrade\r\n');o.write('Sec-WebSocket-Accept: '+key+'\r\n');o.write('\r\n');}else{var frame=decodeDataFrame(e);console.log(frame);if(frame.Opcode==8){//这里也可以发送个结束包来给客户端的onclose中带参数//var buf=new Buffer('\0\0孩子,地球太危险了,快回火星去吧!');//buf.writeUInt16BE(1000,0);//o.write(encodeDataFrame({FIN:1,Opcode:8,PayloadData:buf}));o.end(); //断开连接};};});
}).listen(8000);

总之,客户端直接调用close方法并不会关闭连接,而是发送请求到服务器请求对方。服务器接收请求后可以断开连接。这会触发客户端的close事件。当然,在断开之前也可以发送个同样的断连请求,并包含状态码和原因描述。

WebSocket(伍) 断开连接相关推荐

  1. html5 网络断开,html5 – websocket不断断开连接

    我一直在努力建立一个在浏览器中运行的websocket聊天室.我已经做了一些谷歌搜索,并找到了一个提供示例websocket连接的网站(www.websocket.org/echo.html).但每当 ...

  2. websocket自动断开连接问题

    问题:每过5分钟左右,websocket就会自动关闭 原因:使用了nginx服务,nginx配置: proxy_read_timeout(Default: 60s;),如果一直没有数据传输,连接会在过 ...

  3. WebSocket客户端断开连接后,服务器端的处理机制

    以网页形式存在的客户端,按F5刷新后,服务器端扑捉到disconnect事件: socket.on('disconnect', function(){ log.info("disconnec ...

  4. qt websocket android,QT使用websocket进行长连接

    一般我们用的最多的就是http请求,但是频繁的请求可能对服务造成的压力很大,所以今天谈谈websocket长连接,一句话:简单 1.什么是长连接? A:一次请求连接,终身使用,就可以长久的保持信息的交 ...

  5. 给websocket加入心跳包防止自动断开连接

    var userId = $("#userId").val(); var lockReconnect = false; //避免ws重复连接 var ws = null; //判断 ...

  6. html5 长链接,Vue通过WebSocket建立长连接,连接

    Vue通过WebSocket建立长连接,连接 使用场景: 在项目开发中,后端需要处理一连串的逻辑,或者等待第三方的数据返回来进行处理之后在返回给前端,可能时间会很长,而且前端也不知道后端什么时候能处理 ...

  7. Spring MVC使用webSocket保持长连接

    说明 客户端需要与服务器保持长连接 配置 在pom.xml中加入包依赖 <!-- webSocket start Add by zhangxueliang 2019-02-22 -->&l ...

  8. js 链接websocket马上断开_WebSocket之基于STOMP协议的广播模式实现群聊功能

    又是一个老套的古诗词赏析 不恨此花飞尽,恨西园.落红难缀.--苏轼<水龙吟·次韵章质夫杨花词> WebSocket与STOMP协议 相关简介 WebSocket WebSocket 是一种 ...

  9. js 链接websocket马上断开_SpringBoot+WebSocket实现简单的数据推送

    问题背景 为什么要要用websocket呢?websocket相对于传统http协议有什么优势呢? http协议有一个缺陷,就是通信只能由客户端发起,服务器返回数据,不能做到服务器主动向客户端推送.这 ...

最新文章

  1. numpy常用函数之random.normal函数
  2. cad打开图纸流程图_如何打开cad图纸?cad怎么打开pdf的图纸?
  3. 图解 Elasticsearch 原理
  4. 2.3.3 spring属性注入-注解注入-全注解-配置类扫描
  5. SpringCloud分布式事务,版本一:未加事务版本
  6. LeetCode-Search In Rotated Sorted Array2题解
  7. SAP 前端技术的演化史简介
  8. python时间序列数据分析统计服_python数据分析之:时间序列二
  9. android studio 2.3 instant run,android studio 2.3 instant run not working
  10. python中plot函数的属性_Python matplotlib 学习-绘图函数
  11. 【广告技术】揭秘!腾讯广告是如何有效划分用户群体的
  12. Golang sha256 加密,PHP hash_hmac(‘sha256‘, $string, $key)加密,Js CryptoJS.HmacSHA256(string, key) 加密
  13. Android 系统开发_核心技术篇 -- 深入钻研 JNI
  14. Atitit 分布式之道 attilax著 第4章 通信 第7章 一致性和复制 第8章 容错性 第9章 安全性 第10章 基于对象的分布式系统 第11章 分布式文件系统 第12章 基于Web的分
  15. LeetCode初级算法笔记整理
  16. 人月神话札记:画蛇添足
  17. python中的for什么意思_python中的for是什么
  18. 遗传算法最通俗的讲解案例
  19. 龙芯平台OsTools-Gmac更新
  20. J2EE架构师[转]

热门文章

  1. Linux 系统编程技巧与概念 第14章 字节次序
  2. 计算机专业教研成绩,2018学年第一学期计算机组教研组工作计划
  3. flask web开发:基于python的web应用开发实战_在知乎上学 Python Web 开发篇
  4. 20200705:力扣196周周赛上
  5. 如何解决“企业内控”存在的形式化问题
  6. 智能一代云平台(三十八):单元测试推动开发,如何避免服务之间依赖拖了工期
  7. 世界首个机器人观音在岛国问世,请问AI开光还会远吗?
  8. YY创始人体内植入芯片真相调查
  9. 专栏 | IBM Watson启示录:AI不应该仅仅是炫技
  10. 不狂热不忧虑:观看波士顿动力机器人视频的正确姿势