关于javascript:技术博客|如何使用SSE进行通信

38次阅读

共计 3771 个字符,预计需要花费 10 分钟才能阅读完成。

如何应用 SSE 进行通信

作者:小鹿清孑明,格物钛前端部门,前端工程师

前段时间在 Tensorbay 数据集治理平台前端开发过程中,须要实现一个 action 中的 activity log 实时输入的 feature,很忽然的接触到了一个新技术,急不可待地想要和大家分享一下!

也就拖了 2 个月不到吧,SSE 这不就来了嘛!

WHAT?什么是 SSE?

SSE 全称 Server-Sent Events,字面意思就是服务器向客户端推送信息。

咱们晓得,客户端和服务器端通信个别是通过 http 申请,而 http 申请无奈做到服务器被动推送信息。

然而一种状况除外,那就是客户端通知服务器端接下来申请的这个信息是“流信息”,一个比拟容易了解的例子就是在浏览器中下载文件,当在客户端中登程了一个下载申请之后,客户端会通知服务端接下来申请“流信息”,服务端会向客户端发送继续一直的信息,而客户端也不会敞开连贯,始终期待接管信息。

SSE 就是利用这样一种机制,实现了由服务器端向客户端推送信息的性能。

SSE 听起来和 WebSocket 有点像,然而仔细的敌人能够发现,SSE 是 单向通道,只能实现服务端向客户端发送信息,客户端在第一次触发了 SSE 申请当前就只能接管,并不能回复。

下图示意了 SSE 的大抵流程(笔者亲手临摹作品)

HOW?SSE 如何应用?

理解了 SSE 当前,咱们要怎么应用呢?

在客户端中,SSE 的所有 API 都定义在 EventSource 对象中!

EventSource 是服务器推送的一个网络事件接口。一个 EventSource 实例会对 HTTP 服务开启一个长久化的连贯,以 text/event-stream 格局发送事件, 会始终放弃开启直到被要求敞开。一旦连贯开启,来自服务端传入的音讯会以事件的模式散发至你代码中。如果接管音讯中有一个事件字段,触发的事件与事件字段的值雷同。如果没有事件字段存在,则将触发通用事件。

构造函数

EventSource()

pc = new EventSource(url, configuration)

url 为近程资源地位,configuration 为配置新连贯提供选项。

属性
  • EventSource.onerror: 是一个 event handler, 当产生谬误的时候被调用
  • EventSource.onmessage: 是一个 event handler, 当收到一个 message 的时候被调用
  • EventSource.onopen: 是一个 event handler, 当建设一个链接的时候被调用
  • EventSource.close: 如果链接存在,敞开连贯,readyState 设为已敞开
  • EventSource.readyState: 返回一个只读值, 获取以后链接的状态
  • EventSource.url: 返回一个只读值, 获取以后链接的 URL

用 SSE 实现 action 中的 activity log 实时输入

理解了 SSE 在客户端中的 API 当前,联合实时输入 log 的需要,咱们能够尝试着应用一下啦。

首先分析一下需要,须要在选中某个 activity 的时候,在屏幕左边实时渲染出其 log

那么显然,咱们须要筹备以下内容:

  • 最重要的 服务器端的 URL
  • 获取到 message 当前的 onmessage 回调

筹备好当前,整顿一下逻辑

  • 咱们会在页面中保护两个 state,一个是 EventSource 对象,另一个是须要展现进去的 log 内容 data

      const [data, setData] = React.useState<string>('');
      const [event, setEvent] = React.useState<any>(null);
  • 在 log 页面被渲染的时候和后端建设 sse 连贯

      const newEvent = new EventSourcePolyfill(`urlValue`, { headers});
  • 当后端推送了 message 回来的时候,咱们扭转 data 的值,实现实时输入的成果

      newEvent.onmessage = (e: any) => {logs = logs.concat(`${e.data}\n`);
        setData(logs);
      };
    
      newEvent.onerror = () => {newEvent.close();
      };

看到这里仔细的敌人可能会留神到一个细节!

那就是!

我基本没用到下面提到的 EventSource()啊!

用的是一个如同被封装过的和 EventSource()

很像然而却不一样的 EventSourcePolyfill()啊!

这又是为何啊?!

答案就是

EventSource 不反对传入 headers,也就无奈传给服务端 token。那么对于须要 token 的本资源来讲,不传 token 等于无证驾驶,不给不给滴,所以我就在万能的 gayhub 上调研到了 EventSourcePolyfill,应用它就能够!传给!服务端!token 了!

最终的 curl 如下:

    curl 'https://gas.fat.graviti.cn/gatewayv2/venom-daemon/v1/activity/83639073cb30496c8a5794e9f9ad9276/logs/?&node_id=wf-i5ruzz-qsclf-1529545071&container=main&follow=true' \
  -H 'authority: gas.fat.graviti.cn' \
  -H 'sec-ch-ua:" Not;A Brand";v="99","Google Chrome";v="91","Chromium";v="91"' \
  -H 'accept: text/event-stream' \
  -H 'x-token: 7cd82d49be4b468eb746a283121574e9' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36' \
  -H 'sec-fetch-site: same-origin' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://gas.fat.graviti.cn/dataset/5c2d5481/zj_test/actions/wf/i5ruzz-qsclf?tab=log' \
  -H 'accept-language: zh-CN,zh;q=0.9,en;q=0.8' \
  -H 'cookie: gr_user_id=a7f2dde3-1fb7-4f4e-8ef4-adf94a0f611e; Hm_lvt_88214dfcc23a7cf3e22c61fc2032b3cc=1624525026; _ga=GA1.1.588941179.1620461955; Hm_lpvt_88214dfcc23a7cf3e22c61fc2032b3cc=1625802074; Hm_lvt_16e30fb4f44e9e645bce6c970883ebce=1625197778,1625638587,1625712443,1625802597; _ga_JMKPTKFK1Q=GS1.1.1625824946.4.0.1625824946.0; Hm_lpvt_16e30fb4f44e9e645bce6c970883ebce=1625985701; X-Token=7cd82d49be4b468eb746a283121574e9; 9383fdc1263bf861_gr_last_sent_sid_with_cs1=46cc67df-d7aa-4e46-9d61-75332ce7016c; 9383fdc1263bf861_gr_last_sent_cs1=bf3f0b777057a26f52b661c1f19eaa86; 9383fdc1263bf861_gr_session_id=46cc67df-d7aa-4e46-9d61-75332ce7016c; 9383fdc1263bf861_gr_session_id_46cc67df-d7aa-4e46-9d61-75332ce7016c=true; 9383fdc1263bf861_gr_cs1=bf3f0b777057a26f52b661c1f19eaa86' \
  --compressed

最不一样的就是这里啦:

-H 'accept: text/event-stream' \
-H 'x-token: 7cd82d49be4b468eb746a283121574e9' \

效果图这里这里:

好滴感激大家急躁读完,走过路过的顺便都点个小爱心吧❤️

下次再见啦!

【对于格物钛】:
格物钛智能科技定位为面向机器学习的数据平台,致力于为 AI 开发者打造下一代新型基础设施,从根本上扭转其与非结构化数据的交互方式。通过非结构化数据管理工具 TensorBay 和开源数据集社区 Open Datasets,帮忙机器学习团队和集体升高数据获取、存储和解决老本,减速 AI 开发和产品翻新,为人工智能赋能千行百业、驱动产业降级提供坚实基础。

正文完
 0