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

相关推荐
Smile_Gently2 小时前
前端:最简单封装nmp插件(组件)过程。
前端·javascript·vue.js·elementui·vue
陈敬雷-充电了么-CEO兼CTO8 小时前
DeepSeek核心算法解析:如何打造比肩ChatGPT的国产大模型
人工智能·神经网络·自然语言处理·chatgpt·大模型·aigc·deepseek
luckycoke8 小时前
小程序立体轮播
前端·css·小程序
一 乐8 小时前
高校体育场管理系统系统|体育场管理系统小程序设计与实现(源码+数据库+文档)
前端·javascript·数据库·spring boot·高校体育馆系统
懒羊羊我小弟8 小时前
常用Webpack Loader汇总介绍
前端·webpack·node.js
祈澈菇凉9 小时前
ES6模块的异步加载是如何实现的?
前端·javascript·es6
我爱学习_zwj9 小时前
4.从零开始学会Vue--{{组件通信}}
前端·javascript·vue.js·笔记·前端框架
顾比魁9 小时前
XSS盲打:当攻击者“盲狙”管理员
前端·网络安全·xss
黑客老李9 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
java·运维·服务器·前端·xss
晚风予星9 小时前
简记|LogicFlow自定义BPMN元素节点
前端