伺服器推送 伺服器怎麼向客戶端推送訊息?

2021-10-16 07:14:04 字數 3531 閱讀 7324

最近內部使用的web管理後台系統中新增了乙個報銷單審批的功能,由員工發起報銷申請,然後首先直屬主管進行審批,主管審批通過後流程就到了經理那裡,經理審批通過後流程再轉到財務那裡。

本來這功能無非就是些crud的功能,沒啥難度,但是架不住產品愛搞事啊!產品提出了乙個需求:每個審批操作都需要給下一級處理人主動傳送乙個通知。什麼意思呢?比如直屬主管審批通過後,系統需要在後台給經理主動推送一條訊息,提醒他有報銷單需要他處理。

那麼web專案要怎麼實現伺服器向瀏覽器推送訊息呢?

web專案實現訊息推送有哪幾種方式?

websocket是怎麼建立起連線的?

spring boot整合websocket實現訊息推送總結

傳統的web專案瀏覽器與伺服器基於http協議進行互動,一次互動流程總是先由瀏覽器傳送乙個http請求到伺服器,伺服器收到請求後再返回響應資料。

這樣說伺服器沒有辦法將訊息主動推送到瀏覽器了?其實不然,換個思路既然伺服器不能主動推送訊息,那麼就瀏覽器主動去取好了。

1、ajax輪詢

ajax輪詢原理很簡單,就是讓瀏覽器每隔幾秒鐘就傳送一次請求到伺服器詢問有沒有新訊息。

情景再現:

瀏覽器:伺服器老哥,有沒有新訊息?(發起請求)

伺服器:沒有新訊息(響應)

過了幾秒……

瀏覽器:伺服器老哥,有沒有新訊息?(發起請求)

伺服器:沒有新訊息(響應)

又過了幾秒……

瀏覽器:伺服器老哥,我又來啦!有沒有新訊息?(發起請求)

伺服器:沒有,你好煩啊!(響應)

重複這個……

2、long polling

long polling的原理其實和ajax輪詢類似,但是做了一些優化,long polling採用的是阻塞的方式。瀏覽器發起請求到伺服器,此時如果伺服器沒有新訊息就會一直阻塞不返回響應,直到有新訊息才返回,瀏覽收到返回後,立即再次發起乙個新的請求到伺服器並繼續等待響應。

場景重現:

瀏覽器:伺服器老哥,有沒有新訊息?沒有新訊息我就在這一直等(請求)

伺服器:目前沒有新訊息,你先等著……(連線處於阻塞狀態)

伺服器:來新訊息了!(響應)

瀏覽器:伺服器老哥,有沒有新訊息?沒有新訊息我就在這一直等(請求)

重複這個過程……

不管是ajax輪詢還是long polling,了解流程之後可以看出這兩種方式都算不上完美的方案。ajax輪詢定時發請求,如果這個時候伺服器沒有新訊息,那麼這次連線做的就是無用功;long polling採用阻塞的方式雖然減少了連線的開銷,但是伺服器維持連線同樣需要消耗資源,如果連線併發很大,伺服器將會承受巨大壓力。

websocket的出現就是為了徹底解決伺服器向瀏覽器推送訊息的問題。

websocket是html5新增的一種通訊協議。websocket支援雙向通訊的協議,它和http協議一樣通過tcp連線來進行資料傳輸。但是不同於http協議的是基於websocket瀏覽器和伺服器只需要完成一次握手,兩者之間就直接建立起長連線,並可進行雙向資料傳輸。

websocket協議雖然跟http協議是兩個協議,但其實兩者並不是毫無關係,我更喜歡把websocket協議看作是對http協議的乙個補充,因為websocket建立連線的過程就是借助http協議來完成握手的。

websocket建立連線流程:

瀏覽器向伺服器發出乙個http請求,請求中除了包含常規的資訊,還在請求頭中表明希望將本次通訊的http協議公升級為websocket協議。這個公升級請求協議的過程就叫做握手。

服務端收到公升級請求後會驗證客戶端傳送的請求頭資訊,如果符合規範則同意將http協議替換成 websocket協議,並向瀏覽器返回公升級成功的資訊。

雙方建立起wensocket連線就可以互相推送資訊了。

在瀏覽器中看一下實際建立websocket連線的過程:

瀏覽器傳送http握手請求階段:

伺服器公升級協議返回響應階段:

因為websocket是比較底層的協議,類似於tcp,我們開發web應用並不會直接使用tcp,而是在tcp之上加了一層請求響應模型即http協議。

同樣的,在spring boot專案中整合websocket,我們也不會直接使用websocket,而是使用stomp協議。

stomp之於webscoket就像http之於tcp,是一種基於webscoket的高層協議,stomp提供了乙個可互操作的連線格式,允許stomp客戶端與任意stomp訊息**(broker)進行互動。

整合步驟:

1、在pom.xml檔案裡新增websocket依賴。

2、提供乙個websocket配置檔案:

對外暴露/ws端點作為客戶端連線websocket的入口;

定義了客戶端可以訂閱的主題字首;

3、客戶端頁面:

通過stomp協議發起webscoket連線;

訂閱系統廣播和個人訊息兩個主題;

4、 伺服器推送訊息方法:

所有人只是要連上了伺服器都能收到廣播訊息;

發給指定使用者的訊息只有指定個人能收到;

5、執行專案,瀏覽器開啟兩個頁面分別以使用者a和使用者b兩個不同的身份連線websocket,當伺服器傳送廣播訊息時,使用者a和使用者b都收到了訊息;當伺服器傳送一條給使用者a的訊息時只有使用者a收到了訊息。

伺服器向客戶端推送資料,可以通過http協議以ajax輪詢和long polling等客戶端主動拉資料的方法實現,不管是ajax輪詢還是long polling,都需要不斷的傳送請求,這會造成伺服器資源的浪費。

websocket是一種支援雙向通訊的協議,通過一次http公升級請求完成websocket連線之後就可以多次通訊了。

「分享知識,收穫快樂」

伺服器向客戶端推送訊息的幾種方式

controller public class showtimecontroller responsebody public string gettime controller 記得要在webinitializer中增加servlet.setasyncsupported true public cl...

伺服器與客戶端

建立socket操作,建立流式套接字,返回套接字型大小socksrv socket socket int af,int type,int protocol 第乙個引數,指定位址簇 tcp ip只能是af inet,也可寫成pf inet socket socksrv socket af inet,s...

UDP 客戶端伺服器

udp 客戶端 include include include include include define size 100 define ip 127.0.0.1 define port 10086 int main struct sockaddr in addr 建立socket udp so...