一、前言:

提起长连接,我们并不陌生,最常见的长连接非websocket莫属了。即使没有在项目中实际用过,至少也应该有所接触。长连接指在一次网络通信中,客户端与服务器之间建立一条持久的连接,可以在多次请求和响应中重复使用该连接。这种方式的优点是减少了连接建立和关闭的开销,提高了通信效率,但需要注意控制连接的数量,避免资源浪费。短连接则是每次请求和响应都建立一个新的连接,完成后立即关闭,需要频繁进行连接建立和关闭,效率相对较低。但是这种方式更加灵活,适用于请求量较小、请求频率不高的场景。

二、背景:

最近项目在引用chatgpt智能小助手,最开始采用的是当chatgpt回答完成后一次性返回答案。但这种方式受限于网络及服务较慢的原因导致用户需要等待较长时间,极大的降低了用户的使用体验。经过项目组成员商议决定采取答案逐字返回的形式,以便于用户能更快的得到反馈。

关于长连接技术,主要考虑两种方案websocket和sse

三、原理:

1.websocket概念:WebSocket是HTML5定义的新协议,实现了服务器与客户端之间的全双工通信。WebSocket连接一旦建立,客户端和服务器端处于平等地位,可以相互发送数据,不存在请求和响应的区别。

2、websocket优劣势:优势在于实现了双向通信,劣势在于服务器端的逻辑非常复杂。现在针对不同的后台语言有不同的插件可以使用。

3、sse概念:SSE(Server-Sent Events)是HTML5新增的功能,允许服务器将数据推送到客户端。与长轮询和短轮询不同,SSE不需要客户端先发送请求,而是在服务器端数据有更新时立即发送到客户端

4、sse优劣势:优势在于节约资源,提升应用性能。SSE可以实现只要服务器端数据有更新,就可以马上发送到客户端,不需要建立或保持大量的客户端发往服务器端的请求。另外,SSE的实现非常简单,并且不需要依赖其他插件。劣势在于不是双向通信,只能后台向前台推送。

5、相同点:都是基于tcp,都是可靠的传输协议

6、不同点

  • WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息
  • HTTP是单向的
  • WebSocket是需要浏览器和服务器握手进行建立连接的
  • 而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接

四、应用:

1、sse在chatgpt中的应用

前端代码

import { fetchEventSource } from '@microsoft/fetch-event-source'
let answerContent = ''
fetchEventSource('/chatgptApi/chatgpt_qa_stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ messages }),
async onopen(response) {
if (response.ok && response.status === 200) {
console.log('连接成功')
} else {
console.log('连接异常')
}
},
async onmessage(event) {
// 表示整体结束
if (event.data === '[DONE]') {
console.log('结束')
return
}
if (event.data) {
const data = JSON.parse(event.data)
answerContent += data.content
}
},
async onerror(error) {
console.error('Error:', error)
},
async onclose() {
console.log('关闭连接')
}
})

后端代码

const http = require('http');
const yun = express();
const eventServer = http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'Content-Type,Content-Length,Authorization,Accept,X-Requested-With',
'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS'
});
setInterval(() => {
// 事件要用两个\n结束
res.write('data: The server time is: ' + new Date() + '\n\n');
}, 1000);
req.connection.addListener('close', () => {
console.log('SSE connection closed!');
}, false);
}).listen(4001);

2、websockt在即时聊天中的应用

前端代码

// 创建WebSocket对象
let ws = new WebSocket('ws://localhost:8888') // 连接成功后的回调函数
ws.onopen = function (params) {
console.log('客户端连接成功')
// 向服务器发送消息
ws.send('hello')
}; // 从服务器接受到信息时的回调函数
ws.onmessage = function (e) {
console.log('收到服务器响应', e.data)
}; // 连接关闭后的回调函数
ws.onclose = function(evt) {
console.log("关闭客户端连接");
}; // 连接失败后的回调函数
ws.onerror = function (evt) {
console.log("连接失败了");
};
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,这样服务端会抛异常。
window.onbeforeunload = function() {
ws.close();
}

后端代码

/ 引入插件
const ws = require('nodejs-websocket')
// 只要有用户链接,函数就会执行,会给当前链接的用户创建一个connect对象
const server = ws.createServer((connect)=>{
console.log('连接成功')
// console.log(connect)
// 注册text事件 ,接收用户传递过来的数据
connect.on('text',data=>{
console.log('接收客户端数据---->', data)
// 给所有用户发送消息
broadcast(server,data+"--返回数据")
})
// 连接断开,触发事件close
connect.on('close',()=>{
console.log('用户链接断开--close')
})
// 用户链接断开
connect.on('error',err=>{
console.log('err', err)
}) }).listen(3001,()=>{
console.log('websocket服务启动成功了')
}) // 给所有人发消息
function broadcast(server,msg){
server.connections.forEach(element => {
element.send(msg)
});
}

五、效果:

sse在chatgpt案例中的应用

作者:京东物流 田雷雷

来源:京东云开发者社区 自猿其说Tech

长连接:chatgpt流式响应背后的逻辑的更多相关文章

  1. Openresty的同步输出与流式响应

    Openresty的同步输出与流式响应 默认情况下, ngx.say和ngx.print都是异步输出的,先来看一个例子: location /test { content_by_lua_block { ...

  2. Django的视图流式响应机制

    Django的视图流式响应机制 Django的响应类型:一次性响应和流式响应. 一次性响应,顾名思义,将响应内容一次性反馈给用户.HttpResponse类及子类和JsonResponse类属于一次性 ...

  3. 飘城旅游网pc,流式,响应式布局

    相关视频教程http://pan.baidu.com/s/1o77wirK 我的源码链接:http://pan.baidu.com/s/1czTsKI

  4. 打造自己的ChatGPT:逐字打印的流式处理

    接口的延迟 在调用OpenAI的接口时,不免会有很慢的感觉,抛去地理位置上的网络延迟,大量的延迟往往发生在响应生成的过程中. 因此,如果使用同步接口的话,需要等待响应完全生成之后才能最终显示输出结果, ...

  5. ASP.NET Core Web API 流式返回,逐字显示

    Websocket.SSE(Server-Sent Events)和长轮询(Long Polling)都是用于网页和服务端通信的技术. Websocket是一种全双工通信协议,能够实现客户端和服务端之 ...

  6. Socket的长连接和短连接

    讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建 ...

  7. java如何实现Socket的长连接和短连接

    讨论Socket必讨论长连接和短连接 一.长连接和短连接的概念 1.长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接:后者是每次请求,都新建 ...

  8. Go gRPC教程-服务端流式RPC(三)

    前言 上一篇介绍了简单模式RPC,当数据量大或者需要不断传输数据时候,我们应该使用流式RPC,它允许我们边处理边传输数据.本篇先介绍服务端流式RPC. 服务端流式RPC:客户端发送请求到服务器,拿到一 ...

  9. TCP长连接实践与挑战

    点这里立即申请 本文介绍了tcp长连接在实际工程中的实践过程,并总结了tcp连接保活遇到的挑战以及对应的解决方案. 作者:字节跳动终端技术 --- 陈圣坤 概述 众所周知,作为传输层通信协议,TCP是 ...

  10. jsp实时显示后台批处理进度 - out分块,简单的长连接方式

    这两天在实现一个批处理操作,但是想让前台实时显示后台批处理进度,本想着用复杂一些的框架可以实现异步信息调用 但是鉴于是内部管理系统,且只有一两个人用到这个功能,所以做了一个简单的长连接方式的实时响应 ...

随机推荐

  1. Lambda表达式和链式编程

    一.Lambda表达式 1. Lambda使用条件 Lambda表达式是 JDK8 的一个新特性,可以认为是对匿名内部类的一种简化,但不是所有的匿名内部类都可以简化为Lambda表达式. 只有函数式接 ...

  2. vue中获取所有路由

    在router实例上有options属性:

  3. MySQL WorkBench更换界面成中文的方法

    菜单页面更换 文章目录 菜单页面更换 汉化文件的xml文件我放在下面的网盘中了 1.找到MySQL的安装位置, 总结 汉化文件的xml文件我放在下面的网盘中了 1.找到MySQL的安装位置, 具体安装 ...

  4. Latex-beamer的教程

    Beamer头文件 Latex是一个非常精确且高效的排版工具,其中的beamer作为一个非常强大的模块承担着PPT任务的排版 首先引入头文件来开始: \documentclass{beamer} %h ...

  5. 2022-12-20:二狗买了一些小兵玩具,和大胖一起玩, 一共有n个小兵,这n个小兵拍成一列, 第i个小兵战斗力为hi,然后他们两个开始对小兵进行排列, 一共进行m次操作,二狗每次操作选择一个数k,

    2022-12-20:二狗买了一些小兵玩具,和大胖一起玩, 一共有n个小兵,这n个小兵拍成一列, 第i个小兵战斗力为hi,然后他们两个开始对小兵进行排列, 一共进行m次操作,二狗每次操作选择一个数k, ...

  6. 2022-06-19:给出n个数字,你可以任选其中一些数字相乘,相乘之后得到的新数字x, x的价值是x的不同质因子的数量。 返回所有选择数字的方案中,得到的x的价值之和。 来自携程。

    2022-06-19:给出n个数字,你可以任选其中一些数字相乘,相乘之后得到的新数字x, x的价值是x的不同质因子的数量. 返回所有选择数字的方案中,得到的x的价值之和. 来自携程. 答案2022-0 ...

  7. 2021-07-13:恢复二叉搜索树。给你二叉搜索树的根节点 root ,该树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。进阶:使用 O(n) 空间复杂度的解法很容易实现。你能想出

    2021-07-13:恢复二叉搜索树.给你二叉搜索树的根节点 root ,该树中的两个节点被错误地交换.请在不改变其结构的情况下,恢复这棵树.进阶:使用 O(n) 空间复杂度的解法很容易实现.你能想出 ...

  8. 2021-11-28:有一棵树,给定头节点h,和结构数组m,下标0弃而不用。 比如h = 1, m = [ [] , [2,3], [4], [5,6], [], [], []]

    2021-11-28:有一棵树,给定头节点h,和结构数组m,下标0弃而不用. 比如h = 1, m = [ [] , [2,3], [4], [5,6], [], [], []], 表示1的孩子是2. ...

  9. Python连接es笔记一之连接与查询es

    本文首发于公众号:Hunter后端 原文链接:Python连接es笔记一之连接与查询es 有几种方式在 Python 中配置与 es 的连接,最简单最有用的方法就是定义一个默认的连接,如果系统不是需要 ...

  10. 野火指南者(STM32F103VET6)应用:实现USB虚拟串口(CDC_VPC)

    MCU:STM32F103VET6 开发环境:STM32CubeMX+MDK5 实现USB的虚拟串口不需要去理解USB的底层驱动,只需要STM32CubeMX去配置生成工程即可.在野火的指南者中,是没 ...