websocket應用場景


websocket應用場景

原則上,判斷標准就是以下2個:

  1. 你的應用需要提供給多個用戶同時交流嗎?
  2. 你的應用需要展示服務器端經常變動的數據嗎?

以下是一些典型的應用場景:

  1. 社交 / 訂閱

    比如微信朋友圈的實時更新提醒、點贊或評論的紅點通知,比如qq的特別關注人的動態提醒,比如聊天信息的實時同步,比如新聞客戶端的訂閱通知等等。

  2. 多玩家游戲

    對於在線實時的多人游戲,互動效率是非常重要的,你可不想在扣動扳機之后,你的對手卻已經在10秒鍾之前移動了位置。

  3. 協同辦公 / 編輯

    我們生活在分散式辦公的時代,時常需要在不同地點同時編輯同一份文檔,比如 office文檔、編程文件等。

  4. 股市基金報價

    金融界瞬息萬變——幾乎是每毫秒都在變化。過時的信息也只能導致損失,我們人類的大腦不能持續以那樣的速度處理那么多的數據,需要一些算法來幫我們處理這些事情。當你有一個顯示盤來跟蹤你感興趣的公司時,你肯定想要隨時知道他們的價值,而不是10秒前的數據。使用WebSocket可以流式更新這些數據變化而不需要等待。

  5. 體育實況播放

    在體育播報的體驗中,減低時延是最重要的一點。

  6. 音視頻聊天 / 視頻會議 / 在線教育

    用WebSockets getUserMedia API和HTML5音視頻元素明顯是個不錯的選擇。WebRTC的出現順理成章的成為我剛才概括的組合體,它看起來很有希望,但其缺乏目前瀏覽器的支持。

  7. 基於位置的應用

    越來越多的開發者借用移動設備的GPS功能來實現他們基於位置的網絡應用。比如共享單車、共享汽車、地圖GPS服務、疫情監控目標人的實時運動軌跡、運動員的軌跡分析。借用WebSocket TCP鏈接可以讓數據飛起來。

圖:http輪詢(短輪詢和長輪詢)、websocket、SSE 三種客戶端實時獲取服務端的技術比較
在這里插入圖片描述

概念:

    • 全雙工通訊:
      又稱為雙向同時通信,即通信的雙方可以同時發送和接收信息的信息交互方式。
    • SSE(Server Sent Events)
      就是瀏覽器向服務器發送了一個HTTP請求,保持長連接,服務器不斷單向地向瀏覽器推送“信息”,這么做是為了節省網絡資源,不用一直發請求,建立新連接。不過依然是基於HTTP的。
      優點:SSE和WebSocket相比,最大的優勢是便利,服務端不需要第三方組件,開發難度低,SSE和輪詢相比它不用處理很多請求,不用每次建立新連接,延遲低。
      缺點:如果客戶端有很多需要保持很多長連接,這回占用大量內存和連接數。而且兼容性差,只能用於高級瀏覽器中。

 

vue中

created() {
  this.initWebSocket()
},
destroyed() {
  this.websocketonclose()
},
methods: {
  //websocket
  initWebSocket() {
    if ("WebSocket" in window) {
      const wsuri = baseConfig.WS_URL
      this.websock = new WebSocket(wsuri)
      this.websock.onopen = this.websocketonopen
      this.websock.onerror = this.websocketonerror
      this.websock.onmessage = this.websocketonmessage
      this.websock.onclose = this.websocketonclose
    } else {
      this.$Message.error({
        content: "您的瀏覽器不支持 WebSocket!",
        duration: 5
      });
    }
  },
  websocketonopen() {
    console.log("WebSocket連接成功")
  },
  websocketonerror() {
  },
  websocketonmessage(e) {
if (e.data == 'RELEASE_ROUTE_SUCCESS') {
  this.$Message.success("發布成功")
} else if (e.data == 'RELEASE_ROUTE_FAIL') {
  this.$Message.error("發布失敗")
} else if (e.data == 'UPPER_ROUTE_SUCCESS') {
  this.$Message.success("上架成功")
} else if (e.data == 'UPPER_ROUTE_FAIL') {
  this.$Message.error("上架失敗")
} else if (e.data == 'LOWER_ROUTE_SUCCESS') {
  this.$Message.success("下架成功")
} else if (e.data == 'LOWER_ROUTE_FAIL') {
  this.$Message.error("下架失敗")
} else if (e.data == 'DEL_ROUTE_SUCCESS') {
  this.$Message.success("操作成功")
} else if (e.data == 'DEL_ROUTE_FAIL') {
  this.$Message.error("操作失敗")
}

this.$Modal.remove()
this.refresh('1')

  },
  websocketonclose() {
    console.log("WebSocket關閉成功")
  },
  websocketonsend(a) {
    console.log("發送數據")
    this.websock.send(a)
  },

// 發布
publish(id, a) {
  let params = {
    routeId: id,
    routePublishType: a
  }
  let text = ''
  if (a == '0') {
    text = '發布'
  } else {
    text = '上架'
  }
  let me = this
  params.operateType = 'RELEASE_ROUTE'
  me.websocketonsend(JSON.stringify(params))
  /*        this.$http.request(this, "POST", "/IMC033017.do",params).then(function (response) {
            let body = response.data.body
            if(body.errorCode == '0' || body.errorCode == '00'){
              me.$Message.success(text+'成功')
              me.getData()
            }else {
              me.$Message.error(text+'失敗')
            }
          }).catch(function (error) {
            me.$Message.error(text+'失敗')
          })*/
},
//取消發布
delPublish(id) {
  console.log(id, 'id')
  let params = {
    routeId: id,
    routePublishType: '1'
  }
  let me = this
  params.operateType = 'LOWER_ROUTE'
  me.websocketonsend(JSON.stringify(params))
  /*        this.$http.request(this, "POST", "/IMC033017.do",params).then(function (response) {
            let body = response.data.body
            if(body.errorCode == '0' || body.errorCode == '00'){
              me.$Message.success('下架成功')
              me.getData()
            }else {
              me.$Message.error('下架失敗')
            }
          }).catch(function (error) {
            me.$Message.error('下架失敗')
          })*/
},
//切換頁碼
refresh(e) {
  this.currentPage = e
  this.getData()
},


}

 

 

 

 

作者:Ovear
鏈接:https://www.zhihu.com/question/20215561/answer/40316953
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

一、WebSocket是HTML5出的東西(協議),也就是說HTTP協議沒有變化,或者說沒關系,但HTTP是不支持持久連接的(長連接,循環連接的不算)
首先HTTP有1.1和1.0之說,也就是所謂的keep-alive,把多個HTTP請求合並為一個,但是Websocket其實是一個新協議,跟HTTP協議基本沒有關系,只是為了兼容現有瀏覽器的握手規范而已,也就是說它是HTTP協議上的一種補充可以通過這樣一張圖理解

有交集,但是並不是全部。
另外Html5是指的一系列新的API,或者說新規范,新技術。Http協議本身只有1.0和1.1,而且跟Html本身沒有直接關系。。
通俗來說,你可以用HTTP 協議傳輸非Html 數據,就是這樣=。=
再簡單來說, 層級不一樣

 

二、Websocket是什么樣的協議,具體有什么優點
首先,Websocket是一個持久化的協議,相對於HTTP這種非持久的協議來說。
簡單的舉個例子吧,用目前應用比較廣泛的PHP生命周期來解釋。
1) HTTP的生命周期通過Request來界定,也就是一個Request 一個Response,那么HTTP1.0,這次HTTP請求就結束了。
在HTTP1.1中進行了改進,使得有一個keep-alive,也就是說,在一個HTTP連接中,可以發送多個Request,接收多個Response。
但是請記住 Request = Response , 在HTTP中永遠是這樣,也就是說一個request只能有一個response。而且這個response也是被動的,不能主動發起。

教練,你BB了這么多,跟Websocket有什么關系呢?
_(:з」∠)_好吧,我正准備說Websocket呢。。
首先Websocket是基於HTTP協議的,或者說 借用了HTTP的協議來完成一部分握手。
在握手階段是一樣的
-------以下涉及專業技術內容,不想看的可以跳過lol:,或者只看加黑內容--------
首先我們來看個典型的Websocket握手(借用Wikipedia的。。)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
熟悉HTTP的童鞋可能發現了,這段類似HTTP協議的握手請求中,多了幾個東西。
我會順便講解下作用。
Upgrade: websocket
Connection: Upgrade
這個就是Websocket的核心了,告訴Apache、Nginx等服務器: 注意啦,窩發起的是Websocket協議,快點幫我找到對應的助理處理~不是那個老土的HTTP。
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

首先,Sec-WebSocket-Key 是一個Base64 encode的值,這個是瀏覽器隨機生成的,告訴服務器:泥煤,不要忽悠窩,我要驗證尼是不是真的是Websocket助理。
然后,Sec_WebSocket-Protocol 是一個用戶定義的字符串,用來區分同URL下,不同的服務所需要的協議。簡單理解:今晚我要服務A,別搞錯啦~
最后,Sec-WebSocket-Version 是告訴服務器所使用的Websocket Draft(協議版本),在最初的時候,Websocket協議還在 Draft 階段,各種奇奇怪怪的協議都有,而且還有很多期奇奇怪怪不同的東西,什么Firefox和Chrome用的不是一個版本之類的,當初Websocket協議太多可是一個大難題。。不過現在還好,已經定下來啦~大家都使用的一個東西~ 脫水:服務員,我要的是13歲的噢→_→

然后服務器會返回下列東西,表示已經接受到請求, 成功建立Websocket啦!
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
這里開始就是HTTP最后負責的區域了,告訴客戶,我已經成功切換協議啦~
Upgrade: websocket
Connection: Upgrade

依然是固定的,告訴客戶端即將升級的是Websocket協議,而不是mozillasocket,lurnarsocket或者shitsocket。
然后,Sec-WebSocket-Accept 這個則是經過服務器確認,並且加密過后的 Sec-WebSocket-Key。服務器:好啦好啦,知道啦,給你看我的ID CARD來證明行了吧。。
后面的,Sec-WebSocket-Protocol 則是表示最終使用的協議。

至此,HTTP已經完成它所有工作了,接下來就是完全按照Websocket協議進行了。
具體的協議就不在這闡述了。
------------------技術解析部分完畢------------------

 

你TMD又BBB了這么久,那到底Websocket有什么鬼用,http long poll,或者ajax輪詢不都可以實現實時信息傳遞么。

 

好好好,年輕人,那我們來講一講Websocket有什么用。
來給你吃點胡(蘇)蘿(丹)卜(紅)

三、Websocket的作用
在講Websocket之前,我就順帶着講下 long poll 和 ajax輪詢 的原理。
首先是 ajax輪詢 ,ajax輪詢 的原理非常簡單,讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。
場景再現:
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:沒有。。(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務端:你好煩啊,沒有啊。。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:好啦好啦,有啦給你。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務端:。。。。。沒。。。。沒。。。沒有(Response) ---- loop

 

long poll
long poll 其實原理跟 ajax輪詢 差不多,都是采用輪詢的方式,不過采取的是阻塞模型(一直打電話,沒收到就不掛電話),也就是說,客戶端發起連接后,如果沒消息,就一直不返回Response給客戶端。直到有消息才返回,返回完之后,客戶端再次建立連接,周而復始。
場景再現
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request)
服務端:額。。 等待到有消息的時候。。來 給你(Response)
客戶端:啦啦啦,有沒有新信息,沒有的話就等有了才返回給我吧(Request) -loop

從上面可以看出其實這兩種方式,都是在不斷地建立HTTP連接,然后等待服務端處理,可以體現HTTP協議的另外一個特點,被動性
何為被動性呢,其實就是,服務端不能主動聯系客戶端,只能有客戶端發起。
簡單地說就是,服務器是一個很懶的冰箱(這是個梗)(不會、不能主動發起連接),但是上司有命令,如果有客戶來,不管多么累都要好好接待。

說完這個,我們再來說一說上面的缺陷(原諒我廢話這么多吧OAQ)
從上面很容易看出來,不管怎么樣,上面這兩種都是非常消耗資源的。
ajax輪詢 需要服務器有很快的處理速度和資源。(速度)
long poll 需要有很高的並發,也就是說同時接待客戶的能力。(場地大小)
所以ajax輪詢 和long poll 都有可能發生這種情況。

客戶端:啦啦啦啦,有新信息么?
服務端:月線正忙,請稍后再試(503 Server Unavailable)
客戶端:。。。。好吧,啦啦啦,有新信息么?
服務端:月線正忙,請稍后再試(503 Server Unavailable)

客戶端:


然后服務端在一旁忙的要死:冰箱,我要更多的冰箱!更多。。更多。。(我錯了。。這又是梗。。)

 

--------------------------
言歸正傳,我們來說Websocket吧
通過上面這個例子,我們可以看出,這兩種方式都不是最好的方式,需要很多資源。
一種需要更快的速度,一種需要更多的'電話'。這兩種都會導致'電話'的需求越來越高。
哦對了,忘記說了HTTP還是一個無狀態協議。(感謝評論區的各位指出OAQ)
通俗的說就是,服務器因為每天要接待太多客戶了,是個健忘鬼,你一掛電話,他就把你的東西全忘光了,把你的東西全丟掉了。你第二次還得再告訴服務器一遍。

所以在這種情況下出現了,Websocket出現了。
他解決了HTTP的這幾個難題。
首先,被動性,當服務器完成協議升級后(HTTP->Websocket),服務端就可以主動推送信息給客戶端啦。
所以上面的情景可以做如下修改。
客戶端:啦啦啦,我要建立Websocket協議,需要的服務:chat,Websocket協議版本:17(HTTP Request)
服務端:ok,確認,已升級為Websocket協議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務端:ok,有的時候會告訴你的。
服務端:balabalabalabala
服務端:balabalabalabala
服務端:哈哈哈哈哈啊哈哈哈哈
服務端:笑死我了哈哈哈哈哈哈哈

就變成了這樣,只需要經過一次HTTP請求,就可以做到源源不斷的信息傳送了。(在程序設計中,這種設計叫做回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你)
這樣的協議解決了上面同步有延遲,而且還非常消耗資源的這種情況。
那么為什么他會解決服務器上消耗資源的問題呢?
其實我們所用的程序是要經過兩層代理的,即HTTP協議在Nginx等服務器的解析下,然后再傳送給相應的Handler(PHP等)來處理。
簡單地說,我們有一個非常快速的接線員(Nginx),他負責把問題轉交給相應的客服(Handler)
本身接線員基本上速度是足夠的,但是每次都卡在客服(Handler)了,老有客服處理速度太慢。,導致客服不夠。
Websocket就解決了這樣一個難題,建立后,可以直接跟接線員建立持久連接,有信息的時候客服想辦法通知接線員,然后接線員在統一轉交給客戶。
這樣就可以解決客服處理速度過慢的問題了。

同時,在傳統的方式上,要不斷的建立,關閉HTTP協議,由於HTTP是非狀態性的,每次都要 重新傳輸identity info(鑒別信息),來告訴服務端你是誰。
雖然接線員很快速,但是每次都要聽這么一堆,效率也會有所下降的,同時還得不斷把這些信息轉交給客服,不但浪費客服的 處理時間,而且還會在網路傳輸中消耗 過多的流量/時間。
但是Websocket只需要 一次HTTP握手,所以說整個通訊過程是建立在一次連接/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的信息,直到你關閉請求,這樣就解決了接線員要反復解析HTTP協議,還要查看identity info的信息。
同時由 客戶主動詢問,轉換為 服務器(推送)有信息的時候就發送(當然客戶端還是等主動發送信息過來的。。),沒有信息的時候就交給接線員(Nginx),不需要占用本身速度就慢的 客服(Handler)
--------------------
至於怎么在不支持Websocket的客戶端上使用Websocket。。答案是: 不能
但是可以通過上面說的 long poll 和 ajax 輪詢來  模擬出類似的效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM