目录

前言

一、websocket 协议

1、使用 websocket 协议请求过程解析

2、创建一个 WebSocket 对象

3、WebSocket 的实例方法 和 WebSocket 的事件

(1)、WebSocket 的实例方法

(2)、WebSocket 事件

3、WebSocket 协议与 HTTP 协议的区别

4、WebSocket 与 Socket 的关系

二、Socket

1、客户端-应用层实现心跳包机制

(1)、应用层的心跳包机制

(2)、心跳检测步骤

(3)、心跳检测的优缺点

2、服务端-传输层 TCP 的 KeepAlive 保活机制

(1)、传输层 TCP 的 KeepAlive 保活机制

(2)、KeepAlive 优缺点

3、案例

三、TCP 协议

1、传输控制协议(TCP)

2、TCP保活的必要性

3、TCP 长连接与短连接

(1)、短连接

(2)、长连接


前言

在项目开发时,我们经常需要与服务器进行持续的通讯以保持双方信息的同步。通常这种持久通讯在不刷新页面的情况下进行,消耗一定的内存资源常驻后台,并且对于用户不可见。就聊天的功能来说,我们有以下解决方案:

  • 轮询:

    • 定时轮询:通过 Ajax 轮询请求,每隔一秒或者一段时间请求一次服务器查看是否有未读消息。
    • 长轮询:每一个请求发送到服务器时,服务器将请求卡主,直到有消息时才返回。
  • 使用 WebSocket 协议(推荐)

由于轮询存在明显的弊端:占用服务端地资源, 增大服务端压力,会产生很多无效请求,而且消息存在延时性。所以,推荐使用 WebSocket 协议代替轮询来做即时的、持续的通讯。

一、websocket 协议

推荐一款 在线WebSocket调试 工具。

推荐一个基于 websocket 协议的用来提供持续通信的库——Socket.IO。

WebSocket API 是 HTML5 标准的一部分, 但这并不代表 WebSocket 一定要用在 HTML 中,或者只能在基于浏览器的应用程序中使用。

websocket 是一个基于应用层的网络协议,建立在 TCP 协议之上,和 HTTP 协议可以说是兄弟的关系。我们会先用 HTTP 先进行三次握手,再向服务器请求升级为websocket 协议。

WebSocket 协议将 TCP 的 Socket(套接字)应用在了 web page 上,从而使通信双方建立起一个保持在活动状态连接通道,并且属于全双工(双方同时进行双向通信)。

WebSocket 协议是借用  HTTP 协议 的 101 switch protocol 来达到协议转换的,从 HTTP 协议切换成 WebSocket 通信协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。

1、使用 websocket 协议请求过程解析

连接过程 —— 握手过程:

  • 浏览器、服务器建立 TCP 连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。
  • TCP 连接成功后,浏览器通过 HTTP 协议向服务器传送 WebSocket 支持的版本号等信息。(开始前的 HTTP 握手)
  • 服务器收到客户端的握手请求后,同样采用 HTTP 协议回馈数据。
  • 当收到了连接成功的消息后,通过 TCP 通道进行传输通信。

只需要一次握手,就可以建立持久连接。为了建立一个 WebSocket 连接,浏览器需要向服务器发送一个 HTTP 请求,这个请求和普通的 HTTP 请求不同。请求头中需要附加 Upgrade: WebSocket。这样表示这是一个申请协议升级的 HTTP 请求。其中:

  • Upgrade 和 Connection 字段:告诉服务端,发起的是 webSocket 协议。
  • Sec-WebSocket-Key 字段:是浏览器经过 Base64 加密后的密钥,用来和 response 里面的Sec-WebSocket-Accept进行比对验证。
  • Sec-WebSocket-Version 字段:是当前的协议版本。
  • Sec-WebSocket-Extensions 字段:是对 WebSocket 的协议扩展。
GET /spring-WebSocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

服务器解析对应的请求头进行响应。其中:

  • Upgrade 和 Connection 字段:告诉浏览器,服务已经是基于 webSocket 协议的了,让浏览器也遵循这个协议
  • Sec-WebSocket-Accept 字段:服务端确认后并加密后的 Sec-WebSocket-Accept。
HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

成功响应的状态码为 101,同样也有 Upgrade 表示服务器同意协议升级。成功握手后,HTTP 升级请求底层的 TCP 套接字保持打开状态,客户端和服务器都可以继续发送和接收消息。

请求消息中 Sec-WebSocket-Key 是随机的,服务器会用这些数据构造出一个 SHA-1 的信息摘要,把 Sec-WebSocket-Key 加上一个魔幻字符串。使用 SHA-1 加密,然后进行 BASE-64 编码,结果做为 Sec-WebSocket-Accept 头的值,返回给客户端。

2、创建一个 WebSocket 对象

var ws = new WebSocket('ws://echo.websocket.org');

3、WebSocket 的实例方法 和 WebSocket 的事件

(1)、WebSocket 的实例方法

WebSocket 方法 描述
ws.send() 使用连接发送数据
ws.close() 关闭链接

(2)、WebSocket 事件

WebSocket 事件 描述
open  连接建立时触发。
message  客户端接收服务端数据时触发。
error  通信发生错误时触发。

close

连接关闭时触发。

例如:

ws.onopen = function(e) { console.log("Connection open ..."); ws.send("Hello WebSockets!");
};ws.onmessage = function(e) {console.log( "Received Message: " + e.data);ws.close();
};ws.onerror = function(e) {console.log("error!!!");
};ws.onclose = function(e) {console.log("Connection closed.");
}; 

当然也可以使用 addEventListener 方法添加事件监听,使用 addEventListener 方法添加事件监听时需要把方法名去掉 on。例如:

ws.addEventListener('open', function (event) {ws.send('Hello Server!');
});

3、WebSocket 协议与 HTTP 协议的区别

相同点:

  • 都是基于 TCP 的可靠性传输协议。
  • 都工作在应用层。

不同点:

  • WebSocket 协议:

    • 客户端和服务器只需要一次握手,就可以建立持久连接。
    • 全双工(双向的)通信:客户端和服务器都能主动的向对方发送或接收数据。
    • WebSocket 在建立握手时,数据是通过 HTTP 传输的。但是建立之后,是不需要 HTTP 协议的。建立了 WebSocket 之后服务器不必在浏览器发送 request 请求之后才能发送信息到浏览器,服务器可以主动向浏览器发送数据,而且信息当中不必再带有 head 的部分信息了。与 HTTP 的长链接通信相比,这种方式,不仅能降低服务器的压力,而且信息当中也减少了部分多余的信息,节省了带宽。
  • HTTP 协议:
    • 无状态:对于历史连接是完全没有记忆的, 每一次连接都是新的连接。
    • 无连接、非持久化:一次请求, 一次响应, 不会持续。
    • 半双工(单向的)通信:通信请求只能由客户端发起, 服务端只能对于请求做出应答, 服务端不能主动地向客户端发送数据。
    • HTTP 链接分为短链接,长链接,短链接是每次请求都要三次握手才能发送自己的信息。即每一个 Request 对应一个 Response。长链接是在一定的期限内保持 TCP 连接不断开。

4、WebSocket 与 Socket 的关系

WebSocket 是一个协议。Socket(套接字)是一组接口而不是一个协议,Socket 是为了方便使用 TCP 或 UDP 而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。

二、Socket

1、客户端-应用层实现心跳包机制

Socket 保活指的是:Socket 保持长链接。

常见的 Socket 保活有两种方案:服务端传输层 TCP 的 KeepAlive 保活机制客户端应用层实现心跳包机制

(1)、应用层的心跳包机制

跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。

在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。

心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。

其实,要判定掉线,只需要send或者recv一下,如果结果为零,则为掉线。但是,在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。

在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀……当然,这个自然是要由逻辑层根据需求去做了。

总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。

(2)、心跳检测步骤

  • 客户端每隔一个时间间隔发生一个探测包给服务器
  • 客户端发包时启动一个超时定时器
  • 服务器端接收到检测包,应该回应一个包
  • 如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
  • 如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了

(3)、心跳检测的优缺点

优点:

  • 最大的有点就是自己实现检测机制带来的灵活性。
  • 我们可以做很多事情:控制检测时机,间隔和处理流程。还可以在发出的心跳包中加入额外信息。可以避免上面所说tcp keepalive的缺点。可以检测连接存在,还可以检测连接可用。
  • 还有就是通用性,当传输层使用的是udp的时候,我们socket编程也不需要改变很多代码。socket为我们提供了tcp和udp编程。

缺点:

  • 需要应用层自己实现。自己利用 socket 编程实现。

2、服务端-传输层 TCP 的 KeepAlive 保活机制

(1)、传输层 TCP 的 KeepAlive 保活机制

因为要考虑到一个服务器通常会连接多个客户端,因此由用户在应用层自己实现心跳包,代码较多 且稍显复杂,而利用TCP/IP协议层为内置的KeepAlive功能来实现心跳功能则简单得多。

不论是服务端还是客户端,一方开启KeepAlive功能后,就会自动在规定时间内向对方发送心跳包, 而另一方在收到心跳包后就会自动回复,以告诉对方我仍然在线。 因为开启KeepAlive功能需要消耗额外的宽带和流量,所以TCP协议层默认并不开启KeepAlive功 能,尽管这微不足道,但在按流量计费的环境下增加了费用。另一方面,KeepAlive设置不合理时可能会 因为短暂的网络波动而断开健康的TCP连接。并且,默认的KeepAlive超时需要7,200,000 MilliSeconds, 即2小时,探测次数为5次。对于很多服务端应用程序来说,2小时的空闲时间太长。因此,我们需要手工开启KeepAlive功能并设置合理的KeepAlive参数。

(2)、KeepAlive 优缺点

优点:

  • 使用简单,tcp协议提供的检活(发送探测包 ack包)。

缺点:

  • KEEPALIVE的目的是探测连接是否存在,无法检测能不能发送数据,比如服务器由于负载过大到处无法响应请求,应用层的的原因导致数据无法传输,但是连接还是正常。
  • 如果TCP连接的一端断网或者断电,应用层并不知晓,继续发送数据,这个数据包的优先级是高于KEEPALIVE的数据包,因此这个KEEPALIVE包是无法发送出去的,只有在长时间的重传失败后,我们才能判断连接断开,这段长时间,应用及其容易产生业务逻辑BUG。

3、案例

理解WebSocket心跳及重连机制(五)

js socket心跳链接及断线重连处理

websocket心跳及重连机制

三、TCP 协议

1、传输控制协议(TCP)

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需要4次握手,所以说每个连接的建立都是需要资源消耗和时间消耗的。

2、TCP保活的必要性

TCP 的长连接理论上只要连接建立后,就会一直保持着。但有时有一些防火墙之类的软件会自动检查主机的网络连接状况,比如说如果发现某个连接在几分钟之内都没有数据通讯,则会关闭这个连接。有时客户端与服务器需要实时的检测连接状态,就是需要知道对方是否还在线,如果对方不在线了,需要做相应的处理,这是就需要通过发送心跳包的方法监测链路的状态。

3、TCP 长连接与短连接

(1)、短连接

我们模拟一下 TCP 短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。

(2)、长连接

接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。

【本文参考】

【分布式WebSocket - 1】超详细!WebSocket协议详解

websocket和http的瓜葛以及websocket协议实现

websocket深入浅出

WebSocket介绍和Socket的区别

TCP连接 保持 保活
socket保活方案 Tcp KeepAlive和应用层HeartBeat
Socket如何保证长连接

WebSocket 协议以及 Socket 接口相关推荐

  1. 11-vue移动端项目(小智机器人聊天使用websocket协议使用socket.io客户端第三方包, 让div滚动条自动滚到最底部)

    小智同学 01 - 创建组件 创建组件 & 创建路由 设置入口 02 - 完成静态页面 头部标题 聊天区域 设置内容高度时会出现一个问题: 由于不同的手机型号的高度是不一样的,但是聊天区域的高 ...

  2. workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)...

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  3. 魔坊APP项目-16-种植园、websocket协议、服务端基于socket提供服务(基于房间管理分发信息)、种植园页面展示

    种植园 我们需要完成的种植园,是一个互动频繁,并且要求有一定即时性的模块,所以如果继续基于http协议开发,那么需要通过ajax发送大量http请求,同时因为http本身属于单向通讯,所以服务端无法主 ...

  4. php即时聊天的框架_workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)...

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  5. Jmeter实现WebSocket协议的接口和性能测试方法

    WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex). 浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一 ...

  6. dotnet core 开发无缝兼容Http和Websocket协议的接口服务

    在应用接口开发中往往要针对不同协义开发相应的代理服务,但对于Websocket和http这两种协议来说就有些不同,从实现上来看Websocket可以说是Http的升级子协议, 两者在协议处理上基本一致 ...

  7. 有了Socket协议,为什么还要Websocket协议?

    平时我们打开网页,比如购物网站某宝.都是点一下列表商品,跳转一下网页就到了商品详情. 从HTTP协议的角度来看,就是点一下网页上的某个按钮,前端发一次HTTP请求,网站返回一次HTTP响应. 这种由客 ...

  8. 深入分析websocket协议,从3个方面设计网络应用层协议丨网络编程|网络IO|epoll|socket|网络协议丨c/c++linux服务器开发

    深入分析websocket协议,从3个方面设计网络应用层协议 视频讲解如下: 深入分析websocket协议,从3个方面设计网络应用层协议丨网络编程|网络IO|epoll|socket|网络协议丨c/ ...

  9. WebSocket 协议

    1.1 背景知识 由于历史原因,在创建一个具有双向通信机制的 web 应用程序时,需要利用到 HTTP 轮询的方式.围绕轮询产生了 "短轮询" 和 "长轮询". ...

最新文章

  1. 一本算法刷题必读配套书(附链接)
  2. Java 折半查询_java之折半查询
  3. 从Theano到Lasagne:基于Python的深度学习的框架和库
  4. JVM源码阅读-本地库加载流程和原理
  5. 路飞学城Python-Day171
  6. I_LIKE_CPP 多特游戏下载
  7. 一位工作了10年的C++程序员总结出这些忠告
  8. 在springBoot与quartz 整合中 @Transaction 失效
  9. python apscheduler执行_如何使Python apscheduler在后台运行
  10. ABBYY FineReader 超强OCR识别软件 V15.0.0 特别版
  11. win10无法安装迅雷精简版解决办法
  12. Java中的正则表达式
  13. 现代浏览器:WebM 格式/网络视频的广泛应用
  14. RK339中安卓系统7和9升级最新webView内核步骤
  15. 手写识别ocr java,OCR 指的是手写文字技术_学小易找答案
  16. 2021年危险化学品生产单位安全生产管理人员考试题及危险化学品生产单位安全生产管理人员最新解析
  17. 密码学归约证明——基于伪随机函数的消息鉴别码方案
  18. IDA Crack so文件
  19. 关于暖茶的所有:微电影《暖茶》介绍篇,美文诗歌篇,小说简介篇
  20. 对程序员而言,有什么终身受用的底层知识?

热门文章

  1. JavaScript如何输入输出之如何使用JavaScript优雅编程
  2. 第一代云原生企业米哈游如何让想象发生?
  3. 2018华北五省计算机应用大赛,“远洋航空杯”2019年华北五省(市、自治区) 及港澳台大学生计算机应用大赛隆重举行...
  4. linux图像编辑,Photoflare:Linux下简单的开源图像编辑器
  5. 微服务分布式架构中,如何实现日志链路跟踪?
  6. CF 1646C Factorials and Powers of Two
  7. 十六进制数后跟L/U/UL解析
  8. CSharp 基本知识-数组
  9. 融云 WICC:Unity、Beeto、荔枝、阿里云、StarMaker、LiveMe、积目…花城论剑
  10. 怎么选择国际短信平台?