服务器发送事件SSE和web sockets实时通信

1.服务器发送事件

SSE(服务器发送事件)是围绕只读Comet交互推出的API或者模式。SSE用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的MIME类型必须是text/event-stream,而且是浏览器中的JavaScript API能解析格式输出。SSE支持短轮询、长轮询和HTTP流,而且能在断开连接时候自动确定何时重新连接。那么,此时的Comet就显得容易多了。

1.1SSE API

SSE的JavaScript API与其它传递消息的API很相似。首先要预定新的事件流,必须先创建一个新的EventSource对象,并传递一个入口:

var source = new EventSource("xxx.php);

注意:传入的URL必须与创建对象的页面同源(相同的URL模式,域以及端口),也就是不能跨域。

EventSource的实例有一个readyState属性:

0:正连接到服务器

1:打开了连接

2:关闭了连接

另外:还有以下三个事件:

open:在建立连接时候触发

message :在服务器接收到新事件时触发

error:在无法建立连接时候触发

onmessage事件其实跟ajax中的success事件类似,都是接收到数据之后对数据进行处理。

	source.onmessage = function(event){
		var data = event.data;
		//处理数据
	}

如果想强制立即断开连接并且不再重新连接,可以调用close()方法。

source.close();

1.2事件流

所谓的服务器事件会通过一个持久的HTTP响应发送,这个响应的MIME类型为text/event-stream。响应的格式是文本,最简单的情况是每个数据项都带有前缀data:,例如:

	data:foo

	data:bar

	data:foo
	data:bar

对以上响应而言,事件流中的第一个message事件返回的event.data值为"foo",第二个message事件返回的event.data值为“bar”,第三个message事件返回event.data值为“foo\nbar”(中间的为换行符)。对于多个连续的以data:开头的数据行,将作为多段数据解析,每个值之间以一个换行符分割。只有在包含data:的数据行后面还有空行时,才会触发message事件,因此服务器上生成事件流时不能忘了多添加这一行。


通过id:前缀可以给特定的事件指定一个关联的ID,这个ID行位于data:行前面或者后面都可。

data:foo

id:1

设置了ID之后,EventSource对象会跟踪上一次触发的事件。如果连接断开,回想服务器发送一个包含名为Last-Event-ID的特殊HTTP头部的请求,以便服务器知道下一次触发哪个事件。在多次连接的事件流中,这种机制可以确保浏览器以正确的顺序接收到连接的数据段。

2.Web Sockets

web sockets 目标是在一个单独的持久连接上提供全双工、双向通信。JavaScript中创建了一个web socket之后,会有一个HTTP请求发送到服务器以发起连接。在取得服务器响应之后,简历的连接会时候用HTTP升级从HTTP协议交换转为web socket协议。也就是说,使用标准的HTTP服务器无法实现web socket,只有支持这中协议的专门服务器才能正常工作。
使用自定义的协议而非HTTP协议的好处是,能够在客服端和服务器之间发送非常少量的数据,而不必散心HTTP那样字节级的开销。所以web socket也非常适用于移动端。


2.1Web Socket API

创建Web Socket
var socket = new WebSocket(“ws://www.xxx.com/XXX.php”);

其中的URL可以是任何站点的连接,同源策略对web socket并不适用。
实例化对象之后,浏览器就会马上创建连接。与XHR相似,webSocket也有一个表示当前状态的readyState属性,不过跟XHR并不相同。
WebSocket.OPENING(0):正在创建连接
WebSocket.OPEN(1):已经创建连接
WebSocket.CLOSING(3):正在关闭连接
WebSocket.CLOSE(4):已经关闭连接

WebSocket中没用readystatechange事件,readyState的值永远从0开始。


如果要关闭web socket连接,可以调用close()方法。

调用close()之后,readyState的值立即变为2(正在关闭),随之关闭连接之后会变为3。

2.2发送和接收数据

连接打开之后,可以向服务器发送数据,使用send()方法并传入任意字符串,例如:
var socket = new WebSocket("ws://www.xxx.com/XXX.php");
socket.send("你好");
注意:只能发送纯文本数据,所以对于复杂的数据,在发送之前,要进行序列化。(json序列化数据)

当服务器向客服端发来消息时,WebSocket对象就会触发message事件,处理数据就在message中进行处理。
	socket.onmessage = function(event){
		var data = event.data;
		//处理数据
	}
注意:event.data中的数据是字符串格式的,所以也要做处理之后才能使用。

2.3其他事件

Web Socket对象还有其他三个事件,在连接生命周期的不同阶段触发。

open:在成功建立连接时触发

error:在发生错误的时候触发

close:在连接关闭的时候触发


3.SSE与Web Sockets的区别

1. SSE可以通过常规HTTP协议进行通信,另者则需要特定协议。
2. SSE是单向通信,另者则是双向通信。
3. SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。
4. SSE默认支持断线重连,WebSocket则需要额外部署。



发布了71 篇原创文章 · 获赞 72 · 访问量 48万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章