宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動態(tài)
精選推薦

WS協(xié)議—介紹及原理

管理 管理 編輯 刪除

舉例來說,我們想了解今天的天氣,只能是客戶端向服務(wù)器發(fā)出請求,服務(wù)器返回查詢結(jié)果。HTTP 協(xié)議做不到服務(wù)器主動向客戶端推送信息。

WebSocket 協(xié)議在2008年誕生,2011年成為國際標(biāo)準(zhǔn)。所有瀏覽器都已經(jīng)支持了。它的最大特點(diǎn)就是,服務(wù)器可以主動向客戶端推送信息,客戶端也可以主動向服務(wù)器發(fā)送信息,是真正的雙向平等對話,屬于服務(wù)器推送技術(shù)的一種。

一、傳統(tǒng)的實(shí)現(xiàn)即時通信的方式

1、ajax輪詢

ajax輪詢的原理非常簡單,讓瀏覽器隔個幾秒就發(fā)送一次請求,詢問服務(wù)器是否有新信息。

場景再現(xiàn):

客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:沒有(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:沒有。。(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:你好煩啊,沒有啊。。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:好啦好啦,有啦給你。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:。。。。。沒。。。。沒。。。沒有(Response) —- loop

2、long poll

long poll 其實(shí)原理跟 ajax輪詢 差不多,都是采用輪詢的方式,不過采取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發(fā)起連接后,如果沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完之后,客戶端再次建立連接,周而復(fù)始。

場景再現(xiàn):

客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)
服務(wù)端:額。。 等待到有消息的時候。。來 給你(Response)
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) -loop

從上面可以看出其實(shí)這兩種方式,都是在不斷地建立HTTP連接,然后等待服務(wù)端處理,可以體現(xiàn)HTTP協(xié)議的另外一個特點(diǎn),被動性。何為被動性呢,其實(shí)就是,服務(wù)端不能主動聯(lián)系客戶端,只能有客戶端發(fā)起。

小結(jié):ajax輪詢 需要服務(wù)器有很快的處理速度和資源。(速度)
long poll 需要有很高的并發(fā),也就是說同時接待客戶的能力。(場地大?。?/blockquote>

3、長連接

在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設(shè)為對一個長連接的請求或是采用xhr請求,服務(wù)器端就能源源不斷地往客戶端輸入數(shù)據(jù)。

優(yōu)點(diǎn):消息即時到達(dá),不發(fā)無用請求;管理起來也相對方便。

缺點(diǎn):服務(wù)器維護(hù)一個長連接會增加開銷,當(dāng)客戶端越來越多的時候,server壓力大!

實(shí)例:Gmail聊天

(1)基于http協(xié)議的長連接

      在HTTP1.0和HTTP1.1協(xié)議中都有對長連接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能夠支持,而HTTP1.1默認(rèn)支持.

     http1.0請求與服務(wù)端的交互過程:

  • a)客戶端發(fā)出帶有包含一個header:”Connection: keep-alive“的請求
  • b)服務(wù)端接收到這個請求后,根據(jù)http1.0和”Connection: keep-alive“判斷出這是一個長連接,就會在response的header中也增加”Connection: keep-alive“,同是不會關(guān)閉已建立的tcp連接.
  • c)客戶端收到服務(wù)端的response后,發(fā)現(xiàn)其中包含”Connection: keep-alive“,就認(rèn)為是一個長連接,不關(guān)閉這個連接。并用該連接再發(fā)送request.轉(zhuǎn)到a)

(2)http1.1請求與服務(wù)端的交互過程

  • a)客戶端發(fā)出http1.1的請求
  • b)服務(wù)端收到http1.1后就認(rèn)為這是一個長連接,會在返回的response設(shè)置Connection: keep-alive,同是不會關(guān)閉已建立的連接.
  • c)客戶端收到服務(wù)端的response后,發(fā)現(xiàn)其中包含”Connection: keep-alive“,就認(rèn)為是一個長連接,不關(guān)閉這個連接。并用該連接再發(fā)送request.轉(zhuǎn)到a)

    基于http協(xié)議的長連接減少了請求,減少了建立連接的時間,但是每次交互都是由客戶端發(fā)起的,客戶端發(fā)送消息,服務(wù)端才能返回客戶端消息.因?yàn)榭蛻舳艘膊恢婪?wù)端什么時候會把結(jié)果準(zhǔn)備好,所以客戶端的很多請求是多余的,僅是維持一個心跳,浪費(fèi)了帶寬.

4、Flash Socket

在頁面中內(nèi)嵌入一個使用了Socket類的 Flash 程序JavaScript通過調(diào)用此Flash程序提供的Socket接口與服務(wù)器端的Socket接口進(jìn)行通信,JavaScript在收到服務(wù)器端傳送的信息后控制頁面的顯示。

優(yōu)點(diǎn):實(shí)現(xiàn)真正的即時通信,而不是偽即時。

缺點(diǎn):客戶端必須安裝Flash插件,移動端支持不好,IOS系統(tǒng)中沒有flash的存在;非HTTP協(xié)議,無法自動穿越防火墻。

二、websocket的方式實(shí)現(xiàn)服務(wù)端消息推送

1、什么是socket?什么是websocket?兩者有什么區(qū)別?websocket是僅僅將socket的概念移植到瀏覽器中的實(shí)現(xiàn)嗎?

我們知道,在網(wǎng)絡(luò)中的兩個應(yīng)用程序(進(jìn)程)需要全雙工相互通信(全雙工即雙方可同時向?qū)Ψ桨l(fā)送消息),需要用到的就是socket,它能夠提供端對端通信,對于程序員來講,他只需要在某個應(yīng)用程序的一端(暫且稱之為客戶端)創(chuàng)建一個socket實(shí)例并且提供它所要連接一端(暫且稱之為服務(wù)端)的IP地址和端口,而另外一端(服務(wù)端)創(chuàng)建另一個socket并綁定本地端口進(jìn)行監(jiān)聽,然后客戶端進(jìn)行連接服務(wù)端,服務(wù)端接受連接之后雙方建立了一個端對端的TCP連接,在該連接上就可以雙向通訊了,而且一旦建立這個連接之后,通信雙方就沒有客戶端服務(wù)端之分了,提供的就是端對端通信了。我們可以采取這種方式構(gòu)建一個桌面版的im程序,讓不同主機(jī)上的用戶發(fā)送消息。從本質(zhì)上來說,socket并不是一個新的協(xié)議,它只是為了便于程序員進(jìn)行網(wǎng)絡(luò)編程而對tcp/ip協(xié)議族通信機(jī)制的一種封裝。

socket傳送門: http://therapist.net.cn/ask/thread/30945

websocket是html5規(guī)范中的一個部分,它借鑒了socket這種思想,為web應(yīng)用程序客戶端和服務(wù)端之間(注意是客戶端服務(wù)端)提供了一種全雙工通信機(jī)制。同時,它又是一種新的應(yīng)用層協(xié)議,websocket協(xié)議是為了提供web應(yīng)用程序和服務(wù)端全雙工通信而專門制定的一種應(yīng)用層協(xié)議,通常它表示為:ws://echo.websocket.org/?encoding=text HTTP/1.1,可以看到除了前面的協(xié)議名和http不同之外,它的表示地址就是傳統(tǒng)的url地址。

Websocket其實(shí)是一個新協(xié)議,跟HTTP協(xié)議基本沒有關(guān)系,只是為了兼容現(xiàn)有瀏覽器的握手規(guī)范而已,也就是說它是HTTP協(xié)議上的一種補(bǔ)充可以通過這樣一張圖理解

websocket具有以下幾個方面的優(yōu)勢:

  • (1)建立在 TCP 協(xié)議之上,服務(wù)器端的實(shí)現(xiàn)比較容易。
  • (2)與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務(wù)器。
  • (3)數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
  • (4)可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)。
  • (5)沒有同源限制,客戶端可以與任意服務(wù)器通信。
  • (6)協(xié)議標(biāo)識符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL。

2、websocket的通信原理和機(jī)制

websocket傳輸使用的協(xié)議如下圖:

b7626202306141622554436.png

Websocket是一個應(yīng)用層協(xié)議,它必須依賴 HTTP 協(xié)議進(jìn)行一次握手 ,握手成功后,數(shù)據(jù)就直接從 TCP 通道傳輸,與 HTTP 無關(guān)了。即:websocket分為握手和數(shù)據(jù)傳輸階段,即進(jìn)行了HTTP握手 + 雙工的TCP連接。既然是基于瀏覽器端的web技術(shù),那么它的通信肯定少不了http,websocket本身雖然也是一種新的應(yīng)用層協(xié)議,但是它也不能夠脫離http而單獨(dú)存在。具體來講,我們在客戶端構(gòu)建一個websocket實(shí)例,并且為它綁定一個需要連接到的服務(wù)器地址,當(dāng)客戶端連接服務(wù)端的時候,會向服務(wù)端發(fā)送一個類似下面的http報文

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Version: 13

c77dd202306141623153911.png

客戶端發(fā)起的WebSocket連接報文類似傳統(tǒng)HTTP報文,其中:

  • Upgrade: websocket
    Connection: Upgrade
    這個是WebSocket的核心,告訴服務(wù)器,客戶端發(fā)起的是WebSocket類型請求。Sec-WebSocket-Key是WebSocket客戶端發(fā)送的一個 base64編碼的密文,瀏覽器隨機(jī)生成,要求服務(wù)端必須返回一個對應(yīng)加密的Sec-WebSocket-Accept應(yīng)答,否則客戶端會拋出Error during WebSocket handshake錯誤,并關(guān)閉連接。
  • Sec-WebSocket-Version 是告訴服務(wù)器所使用的 Websocket 協(xié)議版本

服務(wù)端收到報文后會返回下列東西,表示已經(jīng)接收到請求,WebSocket建立成功,來自服務(wù)器的握手如下:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

5814d202306141624246059.png

  • Upgrade: websocket
  • Connection: Upgrade(告訴客戶端即將升級的是WebSocket協(xié)議)
  • Sec-WebSocket-Accept的值是服務(wù)端采用與客戶端一致的密鑰計算出來后返回客戶端的

至此,HTTP已經(jīng)完成它所有工作,接下來就是完全按照Websocket協(xié)議進(jìn)行了。

這里值得注意的是Sec-WebSocket-Accept的計算方法:

base64(hsa1(sec-websocket-key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11))

如果這個Sec-WebSocket-Accept計算錯誤瀏覽器會提示:Sec-WebSocket-Accept dismatch

如果返回成功,Websocket就會回調(diào)onopen事件。

通過查看WebSocket的原理,與HTTP對比,得出結(jié)論:

HTTP長連接中,每次數(shù)據(jù)交換除了真正的數(shù)據(jù)部分外,服務(wù)器和客戶端還要大量交換HTTP header,信息交換效率很低。Websocket協(xié)議通過第一個請求建立了TCP連接之后,之后交換的數(shù)據(jù)都不需要發(fā)送 HTTP header就能交換數(shù)據(jù),這顯然和原有的HTTP協(xié)議有區(qū)別,所以它需要對服務(wù)器和客戶端都進(jìn)行升級才能實(shí)現(xiàn)(主流瀏覽器都已支持HTML5)。

此外還有 multiplexing、不同的URL可以復(fù)用同一個WebSocket連接等功能。這些都是HTTP長連接不能做到的。

基于以上分析,我們可以看到,websocket能夠提供低延遲,高性能的客戶端與服務(wù)端的雙向數(shù)據(jù)通信。它顛覆了之前web開發(fā)的請求處理響應(yīng)模式,并且提供了一種真正意義上的客戶端請求,服務(wù)器推送數(shù)據(jù)的模式,特別適合實(shí)時數(shù)據(jù)交互應(yīng)用開發(fā)。

對比前面的http的客戶端服務(wù)器的交互圖可以發(fā)現(xiàn)WebSocket方式減少了很多TCP打開和關(guān)閉連接的操作,WebSocket的資源利用率高。

3、websocket的創(chuàng)建和常用的屬性方法

以下 API 用于創(chuàng)建 WebSocket 對象。

var Socket = new WebSocket(url, [protocol] );

以上代碼中的第一個參數(shù) url, 指定連接的 URL。第二個參數(shù) protocol 是可選的,指定了可接受的子協(xié)議。

WebSocket 屬性

以下是 WebSocket 對象的屬性。假定我們使用了以上代碼創(chuàng)建了 Socket 對象:

93999202306141626132658.png

CONNECTING:值為0,表示正在連接。

OPEN:值為1,表示連接成功,可以通信了。

CLOSING:值為2,表示連接正在關(guān)閉。

CLOSED:值為3,表示連接已經(jīng)關(guān)閉,或者打開連接失敗。

 var webSocket = new WebSocket(url);
  if(webSocket.readyState == webSocket.CONNECTING){
    console.log('連接正在打開');
  }
 
  webSocket.onopen = function () {
    webSocket.send(consumerId);
    //可以看到 "連接正在打開"并沒有被打印,說明open對應(yīng)的就是OPEN狀態(tài);
    if(webSocket.readyState == webSocket.CONNECTING){
      console.log('連接正在打開1');
    }
    if(webSocket.readyState == webSocket.OPEN){
      console.log('連接已打開');
    }
    sendMsg();
    window.weui.alert('已經(jīng)建立連接');
  };
 
//連接關(guān)閉時觸發(fā)
  webSocket.onclose = function () {
    if(webSocket.readyState == webSocket.CLOSED){
      console.log('連接已關(guān)閉')
    }
      window.weui.alert('連接已斷開');
  };
 
  //連接
  webSocket.onerror = function () {
    window.weui.alert('連接錯誤,請稍后再試');
  };

可以看到,當(dāng)onopen觸發(fā)時,對應(yīng)的就是readyState的OPEN狀態(tài),不包含OPENING;onclose觸發(fā)時,對應(yīng)的就是CLOSED狀態(tài),不包含CLOSING狀態(tài)。

WebSocket 事件

以下是 WebSocket 對象的相關(guān)事件。假定我們使用了以上代碼創(chuàng)建了 Socket 對象:

91ae1202306141626471600.png

WebSocket 方法

以下是 WebSocket 對象的相關(guān)方法。假定我們使用了以上代碼創(chuàng)建了 Socket 對象:

f8a48202306141627028744.png

fe50020230614162736768.png

用websocket發(fā)送接受二進(jìn)制數(shù)據(jù)

WebSocket可以通過ArrayBuffer,發(fā)送或接收二進(jìn)制數(shù)據(jù)。

var socket = new WebSocket('ws://127.0.0.1:8081');
socket.binaryType = 'arraybuffer';
 
// Wait until socket is open
socket.addEventListener('open', function (event) {
  // Send binary data
  var typedArray = new Uint8Array(4);
  socket.send(typedArray.buffer);
});
 
// Receive binary data
socket.addEventListener('message', function (event) {
  var arrayBuffer = event.data;
  // ···
});


請登錄后查看

CRMEB-慕白寒窗雪 最后編輯于2023-06-14 16:28:16

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
2613
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動態(tài) 精選推薦 首頁頭條 首頁動態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動獲取的帖子內(nèi)容,不準(zhǔn)確時需要手動修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊

切換手機(jī)號登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服