接收服务端请求,WebSocket 并非唯一选择!(含:ChatGPT 流推送原理解析)

Hello,大家好,我是 Sunday。

说到推送数据,大家可能首先想到的是 WebSocket

事实上,WebSocket 允许双向通信,自然可以用于服务器到浏览器的消息推送。

然而,如果只需要单向消息推送,HTTP 也可以通过服务器发送事件来实现这一功能。

WebSocket的通信流程如下:

  • 首先,通过HTTP切换协议。 服务器返回状态码101后,协议切换成功。
  • 然后,WebSocket 格式数据的通信开始,一方可以随时向另一方推送消息。

01:啥是 SSE

对于 HTTP 中服务器发送的事件:

服务器返回的 conteng-typetext/event-stream,这是一个可以多次返回内容的流 。服务器端事件通过这种消息类型随时推送数据。我们把它叫做 SSE

在ChatGPT 中。每次回答问题时,它不会立即给出所有答案,而是逐步加载部分。这也是基于SSE的。

现在我们知道什么是 SSE 及其应用,那么如何实现一个 SSE 呢E

02:实现 SSE

创建一个 nest 项目

js 复制代码
    npx nest new sse-test

运行之后可以看到以下内容:

然后,我们可以在 AppController 中添加一个流(stream)接口。

这里并没有通过@Get、@Post等装饰器来标识,而是通过@Sse装饰器表明这是一个事件流类型的接口。

js 复制代码
@Sse('stream')
stream() {
    return new Observable((observer) => {
      observer.next({ data: { msg: 'aaa'} });

      setTimeout(() => {
        observer.next({ data: { msg: 'bbb'} });
      }, 2000);

      setTimeout(() => {
        observer.next({ data: { msg: 'ccc'} });
      }, 5000);
    });
}

它返回的是一个Observable对象,然后内部使用observer.next返回消息。 可以返回任何 JSON 数据。

我们首先返回aaa,2秒后我们返回bbb,5秒后我们返回ccc。

然后创建一个前端页面:创建一个 React 项目。

js 复制代码
    npx create-react-app --template=typescript sse-test-frontend

App.tsx中写入以下代码:

js 复制代码
import { useEffect } from 'react';

function App() {

  useEffect(() => {
    const eventSource = new EventSource('http://localhost:3000/stream');
    eventSource.onmessage = ({ data }) => {
      console.log('New message', JSON.parse(data));
    };
  }, []);

  return (
    <div>hello</div>
  );
}

export default App;

该EventSource是一个本机浏览器API,用于从SSE接口获取响应。 它将把每条消息传递到回调函数 onmessage 中。

我们在 Nest 服务中启用跨域支持。

然后删除react项目的index.tsx文件中的这几行代码,因为它们会导致额外的渲染:

执行 React 项目:npm run start

你可以看到以下内容:

这里的打印,就是服务器发送的事件。

在devtools中,我们可以看到响应的Content-Type是text/event-stream

然后在EventStream中,可以看到每条收到的消息。

这样服务器就可以随时向网页推送消息啦!

我们可以在 MDN 上看到它的兼容性列表:

除IE和Edge外,与其他浏览器不存在兼容性问题。

03:SSE 的应用场景

Server-Sent Events 特别适合 只需要服务器端推送的场景。

比如:GPT 项目、日志的实时推送 等

前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~

相关推荐
程序员爱技术1 小时前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie5 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic6 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿6 小时前
webWorker基本用法
前端·javascript·vue.js