2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

详解如何实现在线聊天系统中的实时消息获取

  • 2019-10-21
  • 本文字数:2677 字

    阅读完需:约 9 分钟

详解如何实现在线聊天系统中的实时消息获取

传统 web 浏览器应用采用客户端主动请求方式,只有在收到浏览器请求时服务端才返回消息,这种模式已经不能满足日益多样化的 web 应用需求,例如:


在线聊天系统:需要实时获取聊天消息。


实时监控系统:需要实时获取监控对象状态。如仪表读数、告警信息等。


随着 html 技术演进,发展出了多种服务器推送技术,用于服务器向浏览器客户端推送消息。

Ajax 轮询

采用 Ajax 定时向服务端发送请求检查有无消息更新。网页定时向服务器发送请求,若服务器有消息推送,则返回消息,否则返回空消息,如下图所示:



这种轮询方式需要发送大量无效请求,大大消耗了服务器资源,且推送消息的实时性较低。

Ajax 长轮询

Ajax 长轮询对前面的 Ajax 轮询方式做了改进,服务端收到请求后,不再立即返回,而是等待有消息推送时返回。网页收到服务端返回的消息后,立即发起一个新的请求,等待下一个推送消息。



采用这种方式的服务端实现比前者复杂,需要维护一个客户端建立的连接列表,当产生对某个客户端的推送消息后找到对应的连接并发送。优势是减少了轮询消耗,发送事件的实时性得到增强。

Server-Send Event

Server-Send Event 是 html5 标准新增的技术,它延用了 Ajax 长轮询的思路,并对其进行了一些规范。Server-Send Event 让服务端可以向客户端流式发送文本消息,并在发送完一个消息后保持请求不结束,连接始终保持。如下图所示:



网页调用 EventSource 接口向服务器发送请求:


Javascript 代码


1 var source = new EventSource(‘http://localhost:8080’);


2source.addEventListener(‘message’, function(e) { console.log(e.data); }, false);


服务器返回的 Content-Type 头必须为 text/event-stream,且返回完一个消息后不关闭请求,后续消息仍然使用同一个请求返回。浏览器会自动以换行符识别每个消息。


响应头-Java 代码


1 Content-Type: text/event-stream


2 X-Accel-Buffering: no


响应体-Java 代码


1 event: userlogin


2 data: {“username”: “John123”}


3


4 event: message


5 data: 123


如果服务端返回的消息通过 nginx 等代理服务器返回给客户端时,可能受到 nginx 缓存机制的影响。某些情况下,nginx 会将服务端返回体缓存起来,等待所有返回接受完毕后再统一返回给客户端,在 server-send event 情况下将导致客户端无法及时接收到消息。需要在返回头中添加 X-Accel-Buffering: no,以防止 nginx 做缓存。

使用华为 API gateway 提供 Server-Send Event 类型的 API 服务建立后端服务

登录华为云,创建弹性云服务器



输入 apt install nodejs 安装 nodejs,使用 nodejs 创建服务器,并输入下列示例代码。


Javascript 代码


01 var http = require(“http”);


02


03 http.createServer(function (req, res) {


04 if (req.url === “/stream”) {


05 res.writeHead(200, {


06 “Content-Type”:“text/event-stream”,


07 “X-Accel-Buffering”:“no”,


08 });


09 res.write("data: " + (new Date()) + “\n\n”);


10 interval = setInterval(function () {


11 res.write("data: " + (new Date()) + “\n\n”); 12 }, 1000);


13


14 req.connection.addListener(“close”, function () {


15 clearInterval(interval);


16 }, false);


17 }


18 }).listen(8080);


上面代码是服务器每秒向客户端发送时间的示例。将上面的代码保存为 server.js,然后执行 nodejs server.js &


就启动了监听在 8080 端口的服务器。

添加安全组

将 8080 端口添加到安全组规则,使得外部可以访问云服务器的 8080 端口。



##创建 API


API 网关提供从内网访问云服务器的能力,不需要申请公网弹性 IP,就可以通过 VPC 通道开放 API。


登录华为云,首先创建 VPC 通道,端口为 8080



将弹性云服务器添加到 VPC 通道:



创建 API,认证类型选择 APP



“请求 Path”填“/stream”,“开启跨域”选项选择开启




创建 API 完成后,发布 API 到 RELEASE 环境。

创建 APP 并绑定 API

在应用管理界面创建一个 APP,并绑定刚刚创建的 API。


创建 OPTIONS 方法的 API

OPTIONS 方法的 API 是提供给浏览器发送跨域请求的预请求使用,同样选择开启跨域(CORS),并将后端配置为 Mock。



点完成创建 API 后,发布 API 到 RELEASE 环境。

创建网页,访问 API

1.要访问 APP 认证方式的 API,需要通过 APP 的 key 和 secret 生成签名,才能校验通过。生成签名使用下面链接下载的javascript SDK


2.由于 IE 浏览器不支持 Server Sent Event,需要从github下载浏览器兼容的 Server Sent Event 实现。


搜索并删除下面四行代码:


Javascript 代码


1 if (url.slice(0, 5) !== “data:” &&


2 url.slice(0, 5) !== “blob:”) {


3 requestURL = url + (url.indexOf("?", 0) === -1 ? “?” : “&”) + “lastEventId=”+ encodeURIComponent(lastEventId);


4 }


3.创建 index.html,内容如下:


Html 代码


01


02


03SSE APP test


04


05


06 SSE APP test


07


<br/>14 var req = new signer.HttpRequest()<br/>15 req.method = “GET”<br/>16 req.host = “<a href="http://d3da6a917a844df3bd02896496b1b75b.apigw.cn-south-1.huaweicloud.com">d3da6a917a844df3bd02896496b1b75b.apigw.cn-south-1.huaweicloud.com</a>”<br/>17 req.uri = “/stream”<br/>18 var sig = new signer.Signer();<br/>19 sig.AppKey = “<your app key>”<br/>20 sig.AppSecret = “<your app secret>”<br/>21 var opts = sig.Sign(req);<br/>22 var source = new EventSourcePolyfill(“<a href="http://d3da6a917a844df3bd02896496b1b75b.apigw.cn-south-1.huaweicloud.com">http://d3da6a917a844df3bd02896496b1b75b.apigw.cn-south-1.huaweicloud.com</a>” + req.uri, {<br/>23 headers: opts.headers<br/>24 });<br/>25 source.onmessage = function (event) {<br/>26 document.getElementById(“a”).innerHTML = event.data;<br/>27 };<br/>28


将刚刚创建的 APP 的 AppKey 和 AppSecret 填入上面指定位置。在本地用浏览器打开此页面,可以看到页面上显示的时间每秒刷新一次。


以上就是对如何实现在线聊天系统中的实时消息获取的详解,想要了解更多,点击“阅读原文”立即体验一番吧~


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/Blm-IFreKREiKlAXo70qWQ36


2019-10-21 13:222121

评论

发布
暂无评论
发现更多内容

YashanDB数据库自动化备份脚本编写教程

数据库砖家

YashanDB数据库自动化运维方案设计与实现

数据库砖家

YashanDB数据库自动扩展功能,助力企业弹性业务需求

数据库砖家

多行业活动管理

微擎应用市场

如何使用龙蜥衍生版KOS,2步实现大模型训练环境部署

OpenAnolis小助手

AI 操作系统 龙蜥大讲堂

多端一体化教育解决方案

微擎应用市场

多行业线下服务订单数字化解决方案

微擎应用市场

YashanDB数据库运维自动化工具介绍

数据库砖家

Cursor 如何保障「代码索引」的安全、高效

Baihai IDP

程序员 AI 智能体 cursor AI 编程

国资委深化“AI+”专项行动 AI法务工具AlphaGPT赋能业务升级

科技汇

HarmonyOS 组件复用 @ReusableV2 装饰器的基本使用 2

万少

harmoyos

领跑 AI 基础设施存储赛道!焱融科技实力登榜「AI Cloud 100 China」

焱融科技

文件存储 大模型 AI基础设施 2025 AI Cloud 100 China

卓正医疗如何用 NocoBase 搭建“家庭医生式”服务体系?

NocoBase

开源 低代码 数字化转型 零代码 医疗行业

YashanDB数据库自动扩容功能详解

数据库砖家

WebGL 软件外包开发流程

北京木奇移动技术有限公司

区块链开发 软件外包公司 RWA开发

MES与ERP深度融合:数据报表、可视化大屏及系统集成技术详解

万界星空科技

制造业 mes ERP系统 万界星空科技mes AI低代码MES

龙蜥衍生技术助力清华登顶TPC物联网数据性能榜首 | 干货推荐

OpenAnolis小助手

操作系统 龙蜥社区 龙蜥操作系统 tpc

YashanDB数据库自动化监控与告警配置指南

数据库砖家

YashanDB数据库运维自动化工具及流程介绍

数据库砖家

CST软件如何设置分布式计算(Distributed Computing)的 TCP-IP子网

思茂信息

cst操作 CST软件 CST Studio Suite

鸿蒙+星闪:一场“1+1>2”的音频蝶变

脑极体

AI

大模型成今年高考志愿神器,超千万用户使用百度AI志愿助手、高考大数据服务

科技大数据

科学智能:全球顶尖学者共聚复旦,共探科研范式变革新引擎

ModelWhale

科学智能 AI4S

龙蜥Confidential AI:开源机密计算AI解决方案,让云端模型安全运行

OpenAnolis小助手

AI 操作系统 机密计算 Confidential AI 龙蜥开源

Zenlayer 推出 AI 模型全球调用解决方案,破局企业部署三大挑战

极客天地

20~30K * 15薪,可惜挂了

王中阳Go

Java 面试

观测云产品更新 | 外部数据源、日志、监控、事件、基础设施等

观测云

这款AI生成播客工具,必须收藏!

Immerse

开源能源管理系统(EMS)深度解析:安全自主可控与实践应用

开源能源管理系统

YashanDB数据库运维常见问题及解决方案

数据库砖家

YashanDB的API文档获取与使用

数据库砖家

详解如何实现在线聊天系统中的实时消息获取_文化 & 方法_余洲_InfoQ精选文章