欢迎访问我的网站与公众号!点击与扫码即可进入,谢谢关注!

构建网络应用的过程中,我们经常需要与服务器进行持续的通讯以保持双方信息的同步。通常这种持久通讯在不刷新页面的情况下进行,消耗一定的内存资源常驻后台,并且对于用户不可见。本文将简要介绍Web通信中常用的四种方式。

一、轮询(略)

前端通过ajax循环向后端请求数据

二、长轮询

长轮询的基本思想是:在每次客户端发出请求后,服务器检查上次返回的数据与此次请求时的数据之间是否有更新,如果有更新则返回新数据并结束此次连接。
通过延迟保持住此次连接,服务器内部查询,直到有新数据时再返回数据结束。

三、sse单向通信:服务器发送数据到客户端

后端以php为例:

  1. 服务器端SSE通过“事件流(Event Stream)”的格式产生并推送事件。
  2. 包含四个字段:event、data、id和retry。用\n换行符结尾
    • event表示事件类型
    • data表示消息内容.单行直接用\n\n结尾,多行前几行用\n结尾
    • id用于设置客户端EventSource对象的“last event ID string”内部属性
    • retry指定了重新连接的时间,默认3秒。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
header('Content-Type: text/event-stream');
header('X-Accel-Buffering: no');
header('Cache-Control: no-cache');
ob_end_clean();
while (true) {
$time = date("r");
echo "id: msg1\n";
echo "event: ping\n";
echo "data: 当前服务器时间\n";
echo "data: The server time is: {$time}\n\n";
ob_flush();
flush();
// sleep(10);
}

前端:

  1. 检测浏览器是否支持SSE,任意方法
    • typeof EventSource != undefined
    • !!window.EventSource
  2. 建立连接,如跨域需要服务器设置好header
  3. 默认事件是message
  4. 如果设置事件event: msg,需要监听addEventListener指定事件msg
  5. 连接一旦建立,就会触发open事件,可以定义相应的回调函数。
  6. 如果发生通信错误(比如连接中断),就会触发error事件。
  7. close方法用于关闭连接。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (typeof EventSource != undefined) {
var sse = new EventSource("http://loclhost:8080/v1/utils/see");
sse.onmessage = function (e) {
console.log(e);
}
sse.open = function (e) {
console.log(e);
}
sse.error = function (e) {
console.log(e);
}
sse.addEventListener("msg1", function(e) {
console.log(e);
}, false);
sse.close()
}

四、websocket双向通信 (略)