現(xiàn)如今,web 項目是非?;鸨模S多企業(yè)都放棄了笨重的 C/S 架構(gòu)軟件,走向了 B/S 架構(gòu)的 web 程序,而 web 項目中,又主要分為電商,OA,管理平臺,論壇,官網(wǎng)幾個類別。其中又以 OA ,和管理平臺項目數(shù)量最多。
今天我們就來介紹一下,在 OA 項目中比較常見的一個功能:實時對話。要說到這個功能,其實在 C/S 架構(gòu)的 OA 項目中我們很早就可以通過 Socket 協(xié)議來實現(xiàn),但是現(xiàn)在很多企業(yè)的 OA 項目轉(zhuǎn)向成了 B/S 架構(gòu),一時間我們又無從下手,直到 HTML5 中 WebSocket 協(xié)議的誕生。實現(xiàn)了在瀏覽器中,我們也可以更簡潔的進行實時對話的功能。
我們首先來了解一下什么是 WebSocket 協(xié)議,還有它與我們常用的 Http 協(xié)議的區(qū)別。
WebSocket:約定了一個通信的規(guī)范,通過一個握手的機制,客戶端(瀏覽器)和服務(wù)器(webserver)之間能建立一個類似tcp的連接,是為了解決客戶端與服務(wù)端實時通信而產(chǎn)生的技術(shù)。他與我們所熟知的 Http 協(xié)議的不同點就在于,Http 協(xié)議是無狀態(tài)的,從某種角度上來講,無狀態(tài)的 Http 協(xié)議非常強大,無論是在做分布式集群還是在其他方面都有著得天獨厚的優(yōu)勢。但是在某些情況下,比如需要客戶端與服務(wù)端長時間連接或者多次請求的時候,又顯得十分無力。

無狀態(tài):無狀態(tài)既是指客戶端與服務(wù)端之間的交互,每一次都是獨立的,一次訪問之后就會斷掉連接。
在出現(xiàn) WebSocket 之前,我們在 web 項目中的實時對話功能可以使用另外兩種方式完成
Ajax輪詢:客戶端與服務(wù)器之間多次發(fā)送請求和響應(yīng),直到獲得結(jié)果已達到目的,缺點在于會向服務(wù)器發(fā)送很多請求,從而消耗大量資源而且很浪費流量。

Long Poll:客戶端每次想服務(wù)器發(fā)送請求多會等待一段時間才會響應(yīng),如果沒有得到結(jié)果就會隔段時間再次發(fā)送請求,直到得到結(jié)果才會結(jié)束,缺點在于會對服務(wù)器造成更大的壓力,需要服務(wù)器能處理更多的并發(fā)。

從以上的對比來看,無論是 Long Poll 還是 Ajax 輪詢都不如 WebSocket 來的方便直接,但是 WebSocket 使用起來也是有限制的,首先需要瀏覽器支持 HTML5,其次是需要服務(wù)器支持,也就是說至少要達到 IIS8 以上版本的 IIS 才能實現(xiàn)。
接下里我們來看看,WebSocket 到底是怎么實現(xiàn)實時對話的。我們所用到的項目還是之前的 WebAPI 的項目。
我們在項目中添加一個公共類和一個一般處理程序,并在 HomeController 中添加一個新的 action?

因為之前的項目我寫了登陸的功能,我們正好可以用到。首先我們將之前登陸成功之后的跳轉(zhuǎn)頁面改成新的地址



上圖的 JS 代碼就是我們講到的 WebSocket 了,其實我們可以將 WebSocket 理解為是對 Socket 協(xié)議的 B/S 架構(gòu)的封裝。而前端代碼我們只是設(shè)置了一個隱藏的文本框,將我們登陸的用戶名賦給他,在設(shè)置兩個按鈕,一個空的文本框就沒有了。
接下來,我們在剛才創(chuàng)建的一般處理程序中寫入已下代碼

上圖中我們首先獲取了 Http 的生命周期中的然后判斷其請求協(xié)議是不是為 WebSocket 協(xié)議

這段代碼是一個異步多線程的委托。

上圖中是另一個公共類,該類實現(xiàn)的是對字典中的用戶信息添加移除以及用戶信息發(fā)送的實際操作的代碼,我們這個程序的中心思想就是,登陸一個用戶,將這個用戶的用戶名以及 Socket 信息存進一個字典中去,然后根據(jù)字典中的信息匹配用戶信息,實現(xiàn)發(fā)送消息,登陸聊天室,離開聊天室的功能。
接下來,我們看一看實際的效果如何。

我們打開兩個瀏覽器,并根據(jù)數(shù)據(jù)庫的信息完成登陸操作,上圖可以看出,現(xiàn)在兩個用戶已經(jīng)完成了登陸操作,并且在第一個登陸的用戶的對話窗口顯示了第二個用戶的登陸提示

接下來我們發(fā)送消息,可以看出發(fā)送消息之后另外的瀏覽器也可以接收到,這樣,我們基于瀏覽器的 WebSocket 項目就完成了。