借着ChatGPT的人机交互聊聊长连接

news/2024/4/12 16:35:19/文章来源:https://blog.csdn.net/hbnn111/article/details/136474122

       ChatGPT这两年可谓风靡全球,尤其是最近Sora视频模型的横空出世以及claude 3模型所具备的浅意识,更是像打开了新世界的大门。本文就从ChatGPT的网页聊天开始聊起(有蹭热度之嫌,哈哈),聊聊长连接的发展历程和应用场景,文章尽量少说生涩的学术性的东西,就是瞎聊。本文也会简单聊聊自己曾经开发的电商客服系统以及个人网站是如何使用长连接的。

        先上个截图,看看ChatGPT使用的长连接:

        嗯,你没看错,ChatGPT由之前的SSE改成了Websocket,可不管用哪个,都使用到了长连接,最初ChatGPT使用SSE将计算得到的数据以流式的方式推送给客户端,不过网上很多文章还停留在2023年,今天我调试发现ChatGPT改用了Websocket。

一、长连接和短连接

        这两个不是什么新概念,短连接是每次请求都需要进行一次完整的TCP连接和释放;而长连接是多个请求可以复用同一个TCP连接,不必每次请求时都要重新建立连接,该请求结束后,也不会立即断开TCP连接。

       最早的HTTP/1.0默认都是短连接,后续引入了Keep-Alive,以及后续的HTTP/1.1,Http/2,Http/3都是默认长连接。短连接导致每次请求js,css,img这种静态文件时,每次都需要重新建立TCP连接进行请求,可想而知这种操作性能较差;后续的长连接就解决了这种问题。去年我们在处理生产事故时,一个系统使用了Nginx做反向代理,Nginx到Server使用的是短连接,导致在高并发时,出现了大量的TIME_WAIT,系统处理性能下降,并发量一直上不去,改成长连接之后,吞吐量立马就上来了。

        长连接几乎是所有系统的选择,比如我们所知道的RocketMQ的broker和consumer之间的长连接、Dubbo provider 与注册中心,provider和consumer,以及consumer与注册中心的长连接、游戏应用、聊天室、协作平台等等,都可以看到长连接的身影。

        Nacos也是在2.x版本开始引入了长连接,使得性能相比于1.x版本有了成倍数的提升。

c261d2dfc44440a1bb72001361c5abdc.png

二、长连接的实现方式

  1、HTTP Keep-Alive

        上面提到了,在HTTP/1.0时代,所有的连接都是短连接,这种低效的通信方式已经完全满足不了日益发展的实际业务需求了,因此后来引入了Keep-Alive(大家可以自行搜索与TCP的Keep-Alive的区别),长连接由此到来,HTTP/1.0,需要显示配置请求头的Connetion:Keep-Alive,而HTTP/1.1版本是默认支持的,如果Connection传close,就会关闭。当配置Nginx时,默认是http/1.0,就需要配置长连接,部分代码如下:

keepalive_requests 1000;keepalive_timeout 60;server {proxy_set_header Connection "";proxy_http_version  1.1;}

2、WebSocket

      长连接只是提升基本性能的一种手段,如果希望能够实现即时通信,如服务端消息推送、聊天儿的话,就需要引入其他的方案。那最早的实现方式是客户端要主动轮询,轮询包括短轮询和长轮询(通常大家把短轮询就叫轮询,我为了区分就加个短字)。

        短轮询是不断地向服务器发送HTTP请求,有没有数据都直接返回,没有数据就再次发请求;长轮询(Comet)是向服务器发一次HTTP请求,如果服务端没数据就挂起请求,待到一定时间内还没有数据再返回。可见长轮询相比于短轮询有所改进的,减少了请求次数,但两者本质是一样的。这种经常性地发送HTTP请求势必造成了资源带宽的浪费,而且这也会造成同步的延迟。这突然让我想到了非阻塞IO,他也是不断发起系统调用询问数据有没有准备好,直到IO多路复用机制的出现才改变这种方式。

        那针对上面的问题,WebSocket可以较好地解决,Websocket是随着HTML5(html的版本,2008年正式发布)面世的。一经出现,广受好评和推广,这是因为其在技术上完全改变了过去的即时通信的实现方式,也大大提升了用户的使用体验。Websocket在客户端和服务端保持唯一的连接前提下,服务端可以主动把消息发给服务端,而且是全双工通信(全双工和半双工这两个算是通信领域的名词,他代表了我们通信的方式。全双工表示通信双方可以同时发数据;半双工是同一时刻只能有一方数据;还有一种叫单工,即只允许一个方向传数据,如广播电台)。

        现在我们经常看到的很多的网页聊天室,如电商平台的客服,基本上也都是通过Websocket的方式实现的。下面是真实的一个示意图:

        5c6370a9affe4540b0fe9ccddd51bfac.png

       之前在小米时,对接拼多多,拼多多的退款通知接口就是Websocket实现的,之所以这么做的原因就是用户在拼多多的退款申请通过后,拼多多会实时推送给小米有品,有品做后续的退款动作,避免因为定时轮询产生的延迟问题。对接过淘宝,京东的同学应该都知道,我们通常会通过定时轮询平台提供的接口同步订单和退款单,以便做后续的转单、发货或退款操作,但这种实现方式最大的问题就是存在延迟,有可能你都发完货了,才收到退款通知。下面是简单的示意图(注:wss是ws的安全版,类似于https和http的关系):

        ce903595c3e144c790544eda4bfcaa7e.png

        

        我画了一个Websocket连接建立的过程示意图:

adfb9112319b47c092eaf1c161d30ab7.png

        从上面流程图可以看到,Websocket的建立也要从HTTP协议开始的,这是因为浏览器为了统一不同的使用场景,第一次都会以HTTP协议进行通信,并不是说Websocket是基于HTTP,Websocket和HTTP都是应用层协议,两者互不隶属。

TCP报文:

GET /ws/chat/haibo/dhdwdwdnwdindo/ HTTP/1.1
Host: 127.0.0.1:8000
Connection: Upgrade   //告诉浏览器,我要升级
Upgrade: websocket
Origin: http://127.0.0.1:8000
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Sec-WebSocket-Key: ++EcxfMKJZv5ZPzm/Ah0+Q==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

服务端:

HTTP/1.1 101 Switching Protocols  #101表示握手成功
Server: Daphne
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: MDda/nVP5hymfRIxrEqsDeTXFTA=.......9...h...9...z...f..{"message": "hello\uff1ahaha"}."{"message": "hello\uff1ahahatest"}..4WZj....HB!..(..un7g....;.......z.4SyV....

       Websocket具体的解释和字段含义这里不赘述,可参考标准:The WebSocket Protocol 。

        我前几年在写电商网站的时候,自己写了一个客服系统,用Python(django+channels)和LayIM实现的,先上图:

用户客服咨询:

d8780d63ac0e43c7b4fe7bd06992957f.png

客服端:

e82a616b9e0a466ebc3913154a23440c.png

F12可以看到其创建的Websocket,2201809314是用户id,每个用户创建了一个聊天室:

184355e7fc58444d993cd5667b00c9ec.png

其所发送的消息也都在连接上传递,双方也都可以主动发送消息(右侧红框里就是双方发送的消息):

703039e367eb44b1a01d90a9b610b4a7.png本文不展示具体代码,感兴趣的可以和我联系,我会免费提供代码。    

3、SSE

      SSE是基于HTTP协议的,这是和Websocket的不同点之一,而且他只能实现服务器到客户端的单向数据推送,不是双向通信的,这也是和Websocket的不同。SSE技术也是在ChatGPT中得到了应用,像淘宝的监控通知、股票的数据推送也都有用到,实时消息推送采用SSE也是一种较好的选择。

      这里展示一下demo的SSE请求和响应:

2c38cbaeae6c4cd58e3fa13f456619b5.png

数据推送:

a97a0041cbd34157a6f2fdba6769fc2a.png

4、Http/2

     http/2正式推出是2015年,想想也快10年了,目前基本上大家也都换成了http/2,其特点就是默认就是支持长连接,除此之外,还具备多路复用、二进制帧、头部压缩、服务器推送等优点,因此在性能上要甩出Http/1.x一大截,我在前两年也已经把自己的网站升级到http/2了,性能是肉眼可见的提升。

6d2cae1f85b94bb5a546063c4cb553de.png

dff333ab3ab94a41a3c2a586d331610b.png

       上面说到http/2既支持长连接,又支持服务端主动推送数据,那是不是就可以取代Websocket和SSE了呢?

        答案是不能,http2的服务端推送的定位就不一样,其目的是一次性提前将客户端可能请求的资源推送到客户端缓存,如js,css,img这种静态资源。诸如网页访问,数据首先会推送到浏览器缓存,当客户端发出请求时,直接从缓存中拿出请求数据即可。而Websocket实现的是实时的双方通信,SSE是服务器实时的流式推送。至少在一段时间内,Websocket和SSE是不会被淘汰的。

5、Http/3的QUIC

        好多人可能没听过QUIC协议,它是Http3所使用的协议,基于UDP实现的。是的,你没看错,未来的Http协议不再使用TCP,而是使用UDP协议,本文不讲述QUIC协议的原理,先说一个最大用处。

        我们在使用手机过程中,如果网络从移动网络切换到WIFI,或者WIFI切换到移动网络,往往会出现卡顿,卡顿时间不定。之所以出现这种现象是因为当前都是基于TCP连接的,一个TCP连接是由四元组组成的,包括源ip,目的ip,源port,目的Port,切换网络会导致源ip发生变化,需要重新建立连接。

6d4a4a8f5c2c49aea685bab2c8a1e3b5.png

        而QUIC协议规避了这点,两者可以创建连接id,类似于会话id,只要客户端和服务端双方设备id没有发生改变,就不会断线重新连接,这种好处就会大大提升用户的体验感。

7c7341df32b0435c970c32d9845c943d.png

 刚才我用wireshark抓了两个包:

 SCID(souce connection id) 、DCID(dest connection id):

08aed9f9dd7f4b29a897bc8400cf4b6a.png     

UDP:

a9b7421c84024860987e6fd1888b6ab4.png

        QUIC协议目前还没有大面积的推广,很多的客户端,如浏览器可能还不支持,但我相信不久的将来,QUIC一定会占据主要地位。

三、总结

        经济基础决定上层建筑,说的一点也不错。基础就是基石,基础决定了最终的高度,看似很基础的通信原理却影响着科技与生活的方方面面。说到这儿,我感觉挺悲哀的,当前计算机领域的基础建设都是欧美创造的,他们是Creator,而国内几乎所有人都是照搬过来,然后去做可以创造财富的应用,他们开发者想的是如何改变世界,我们则以利益为锚点,这就是价值观的不同。当然这并不是我们个人的错,是环境导致的,不搞钱,我们就得饿死。如今国内只有华为一家才真的可以与国外媲美,任正非曾经说过,“华为的理想是为了全世界服务”。我相信他说的话,如果他要是急功近利,就不用费尽周折大搞芯片研发,直接像其他设备商一样,买买买,然后上市圈钱就完了。

        今天早晨在读《认知驱动》这本书时,书中正好提到过,当你在做一件事时,不要太急功近利,而要多想一些利他的事,就像日本商业大神稻盛和夫,他在创造DDI之前一直在思考自己的想法是不是纯粹,是真的为了自己的国民,还是自己想出风头?经过半年的反省,他坚定了自己的信念,即他只考虑如何为国民利益着想,而不是为了自己,最后创造了蚍蜉撼大树的典范,吃掉NTT的一半市场,占据了半壁江山,他也真的为老百姓做出了贡献,降低了通讯资费。这个小故事想说,当你在做一件事时,如果考虑利他多余利己,那么你就会更加专心、更加耐心地去做它,直到成功,而成功后最终受益的还是自己,也就是说利他最终的结果一定还是利己。而国内这方面的欠缺也解释了为什么国内芯片领域如此薄弱,汉芯诈骗事件尤为深刻。

     希望华为能够掀起这股浪潮,让中国变得更加强大,也愿国家早日收复台湾,完成民族统一大业!!!

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_998958.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

148个Chatgpt关键词汇总-有爱AI实战教程(二)

演示站点: https://ai.uaai.cn 技能模块 官方论坛: www.jingyuai.com 京娱AI 导读:在使用 ChatGPT 时,当你给的指令越精确,它的回答会越到位,举例来说,假如你要请它帮忙写文案,如…

来说说看到的求职路上可以提高的地方——简历

要进行求职的时候应该遇到的第一件事情就是简历。 随着看到的简历越来越多,也发现了一些问题,来开个帖子来说说这些问题。 格式 让参加面试的人最头疼的地方就是简历格式没有空格。 最近发现好多人的简历格式上都不空格,很多内容完全都在…

IntelliJ IDEA自定义关闭当前文件的快捷方式

前言 idea中关闭当前标签页的默认快捷键是CtrlF4,这个组合键在键盘上操作起来很是不方便,我们可以在设置中自定义自己习惯的快捷方式。 自定义步骤 要在 IntelliJ IDEA 中将关闭当前文件的快捷方式设置为 Alt Q,请按照以下步骤操作:打开 …

Android应用界面

概述:由于学校原因,估计会考,曹某人就浅学一下。 目录 View概念 创建和使用布局文件 相对布局 线性布局 水平线性布局 垂直线性布局 表格布局 帧布局 扁平化布局 Android控件详解 AdapterView及其子类 View概念 安卓中的View是所…

Qt初识 - 编写Hello World的两种方式 | 对象树

目录 一、通过图形化方式,在界面上创建出一个控件 二、通过代码方式,创建Hello World 三、Qt 内存泄漏问题 (一) 对象树 一、通过图形化方式,在界面上创建出一个控件 创建项目后,打开双击forms文件夹中的ui文件,可…

Mysql8的优化(DBA)

Mysql8的优化 1、Mysql的安装优化1.1 修改配置参数(命令行、配件文件)1.1.1 命令行修改配置参数1.1.2 参数持久化1.1.3 Mysql多实例启动,以及配置密码文件 1.2 查询表的相关参数,以及表空间管理 2、Mysql高级优化(SQL&…

CNC机加工引入复合机器人可以提高生产效率,降低成本

CNC加工企业在过去依赖大量的人工来完成生产线上的各项任务,包括CNC机床的上下料、物料搬运以及部分装配工作。然而,随着产能需求的不断增长和人工成本的持续上升,企业逐渐意识到自动化升级的重要性与迫切性。 面临的挑战与需求: …

【DUSt3R】2张图2秒钟3D重建

【DUSt3R】2张图2秒钟3D重建 1. DUSt3R是一种用于稠密和无约束立体三维重建的方法,其实现步骤如下:2. 实际运行效果3. 运行结果4. 自问自答4.1 为社么这里要是使用transform模型呢?4.2 CroCo(通过跨视图完成3D视觉任务的自我监督预训练的一个研究)在DUSt3R的作用是什么,为…

云计算项目十:ES集群安装|部署kibana

ES集群安装 部署ES集群,用于ELK日志分析平台的构建 es-0001 主机更改 /etc/hosts [rootes-0001 ~]# vim /etc/hosts 192.168.1.71 es-0001 192.168.1.72 es-0002 192.168.1.73 es-0003 192.168.1.74 kibana 192.168.1.75 logstash # 将最新的/etc/hosts配置文件更…

javaSE-----继承和多态

目录 一.初识继承: 1.1什么是继承,为什么需要继承: 1.2继承的概念与语法: 二.成员的访问: 2.1super关键字 2.2this和super的区别: 三.再谈初始化: 小结: 四.初识多态: 4.1多…

Visual Studio 2019重装vs2019打不开.netcore项目

无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBuild 的 17.4.0 版本。当前可用的 MSBuild 版本为 16.11.2.50704。请将在 global.json 中指定的 .NET SDK 更改为需要当前可用的 MSBuild 版本的旧版本。 无法打开项目文件。 .NET SDK 的版本 7.0.306 至少需要 MSBui…

go语言添加代理

LiteIDE 工具->管理 https://mirrors.aliyun.com/goproxy/或https://goproxy.cn,direct 命令行 go env -w GOPROXYhttps://goproxy.cn,direct

C.C语言分支和循环语句

文章目录 一. 什么是语句 二. 分支语句(选择结构) 2.1. if 语句 2.1.1. 语法结构 2.1.2. 悬空else 2.1.3. 书写形式的对比 2.1.4. 练习 2.2. switch 语句 3.2.1. 语法结构 3.2.2. 在switch语句中的 break 3.2.3. default子句 3.2.4. 练习 三…

Android 12.0 系统默认打开OEM解锁开关功能实现

1.前言 在12.0的系统rom定制化开发中,在9.0系统以后为了设备的安装,系统开始启用oem机制,所以在adb push文件就需要先oem解锁,然后才可以 进行相关操作,所以就需要默认打开oem解锁的开关,来方便oem解锁功能的实现 如图: 2.系统默认打开OEM解锁开关功能实现的核心类 pack…

找不到本地组策略编辑器解决办法

创建记事本写入以下命令 echo offpushd "%~dp0"dir /b %systemroot%\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >gp.txtdir /b %systemroot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-…

MySQL 学习笔记(基础篇 Day3)

「写在前面」 本文为黑马程序员 MySQL 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容: 1. MySQL 学习笔记(基础篇 Day1) 2. MySQL 学习笔记&#xff08…

阿里云游戏访问与下载加速解决方案

随着全球化的发展,越来越多的企业开始将业务扩展到海外市场。然而,海外市场的挑战也是显而易见的。例如在游戏企业进军海外市场的过程中,网络延迟是一个常见的问题。由于地理位置的限制,海外用户登录访问游戏和游玩时,…

尚硅谷JavaScript高级学习笔记

01 准备 JavaScript中函数是对象。我们后续描述构造函数的内存模型时,会将构造函数称为构造函数对象。 02 数据类型 typeof 运算符来查看值的类型,它返回的是类型的字符串值 会做数据转换 03 相关问题 04数据_变量_内存 05相关问题1 06相关问题2 …

苍穹外卖学习-----2024/03/08

1.新增菜品 工具类AliOssUtil .java Data AllArgsConstructor Slf4j public class AliOssUtil {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;/*** 文件上传** param bytes* param objectName* return*/pub…

分享axios+MQTT简单封装示例

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在19…