服務器發送事件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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章