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

网友投稿 328 2022-11-12

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

序言

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

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

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

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

Ajax轮询

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

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

Ajax长轮询

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

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

Server-Send Event

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

var source = new EventSource('function(e) { console.log(e.data); }, false);

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

响应头

Content-Type: text/event-stream

X-Accel-Buffering: no

响应体

event: userlogin

data: {"username": "John123"}

event: message

data: 123

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

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

var = require(" (req, res) { if (req.url === "/stream") { res.writeHead(200, { "Content-Type":"text/event-stream", "X-Accel-Buffering":"no", }); res.write("data: " + (new Date()) + "\n\n"); interval = setInterval(function () { res.write("data: " + (new Date()) + "\n\n"); 12 }, 1000); req.connection.addListener("close", function () { clearInterval(interval); }, false); } }).listen(8080);

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

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

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

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

创建APP并绑定API

创建OPTIONS方法的API

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

创建网页,访问API

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

2.由于IE浏览器不支持Server Sent Event,需要从Sent Event实现。

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

if (url.slice(0, 5) !== "data:" &&

url.slice(0, 5) !== "blob:") {

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

}

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

SSE APP test

SSE APP test

09

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:英创信息技术WinCE平台C#例程要点介绍
下一篇:解决因jdk版本引起的TypeNotPresentExceptionProxy异常
相关文章

 发表评论

暂时没有评论,来抢沙发吧~