接收服务端请求,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。欢迎来撩~~~~~~~~

相关推荐
dawn1912283 分钟前
SpringMVC 中的域对象共享数据
java·前端·servlet
newxtc40 分钟前
【爱给网-注册安全分析报告-无验证方式导致安全隐患】
前端·chrome·windows·安全·媒体
dream_ready2 小时前
linux安装nginx+前端部署vue项目(实际测试react项目也可以)
前端·javascript·vue.js·nginx·react·html5
编写美好前程2 小时前
ruoyi-vue若依前端是如何防止接口重复请求
前端·javascript·vue.js
flytam2 小时前
ES5 在 Web 上的现状
前端·javascript
喵喵酱仔__2 小时前
阻止冒泡事件
前端·javascript·vue.js
GISer_Jing2 小时前
前端面试CSS常见题目
前端·css·面试
AI王也2 小时前
ChatGPT搭上langchain的知识库RAG应用,效果超预期
人工智能·chatgpt·langchain·aigc
八了个戒2 小时前
【TypeScript入坑】什么是TypeScript?
开发语言·前端·javascript·面试·typescript
不悔哥2 小时前
vue 案例使用
前端·javascript·vue.js