HTML5 學習筆記(五)——WebSocket與消息推送

来源:http://www.cnblogs.com/SeeYouBug/archive/2016/12/03/6127061.html
-Advertisement-
Play Games

B/S結構的軟體項目中有時客戶端需要實時的獲得伺服器消息,但預設HTTP協議只支持請求響應模式,這樣做可以簡化Web伺服器,減少伺服器的負擔,加快響應速度,因為伺服器不需要與客戶端長時間建立一個通信鏈接,但不容易直接完成實時的消息推送功能,如聊天室、後臺信息提示、實時更新數據等功能,但通過polli ...


B/S結構的軟體項目中有時客戶端需要實時的獲得伺服器消息,但預設HTTP協議只支持請求響應模式,這樣做可以簡化Web伺服器,減少伺服器的負擔,加快響應速度,因為伺服器不需要與客戶端長時間建立一個通信鏈接,但不容易直接完成實時的消息推送功能,如聊天室、後臺信息提示、實時更新數據等功能,但通過polling、Long polling、長連接、Flash Socket以及HTML5中定義的WebSocket能完成該功能需要。

一、Socket簡介

Socket又稱"套接字",應用程式通常通過"套接字"向網路發出請求或者應答網路請求。Socket的英文原義是“孔”或“插座”,作為UNIX的進程通信機制。Socket可以實現應用程式間網路通信。

Socket可以使用TCP/IP協議或UDP協議。

TCP/IP協議

TCP/IP協議是目前應用最為廣泛的協議,是構成Internet國際互聯網協議的最為基礎的協議,由TCP和IP協議組成:
TCP協議:面向連接的、可靠的、基於位元組流的傳輸層通信協議,負責數據的可靠性傳輸的問題。

IP協議:用於報文交換網路的一種面向數據的協議,主要負責給每台網路設備一個網路地址,保證數據傳輸到正確的目的地。

UDP協議

UDP特點:無連接、不可靠、基於報文的傳輸層協議,優點是發送後不用管,速度比TCP快。

二、WebSocket簡介與消息推送

B/S架構的系統多使用HTTP協議,HTTP協議的特點:

1 無狀態協議
2 用於通過 Internet 發送請求消息和響應消息
3 使用埠接收和發送消息,預設為80埠
底層通信還是使用Socket完成。

HTTP協議決定了伺服器與客戶端之間的連接方式,無法直接實現消息推送(F5已壞),一些變相的解決辦法:

雙向通信與消息推送

輪詢:客戶端定時向伺服器發送Ajax請求,伺服器接到請求後馬上返迴響應信息並關閉連接。  優點:後端程式編寫比較容易。  缺點:請求中有大半是無用,浪費帶寬和伺服器資源。  實例:適於小型應用。

長輪詢:客戶端向伺服器發送Ajax請求,伺服器接到請求後hold住連接,直到有新消息才返迴響應信息並關閉連接,客戶端處理完響應信息後再向伺服器發送新的請求。  優點:在無消息的情況下不會頻繁的請求,耗費資小。  缺點:伺服器hold連接會消耗資源,返回數據順序無保證,難於管理維護。 Comet非同步的ashx, 實例:WebQQ、Hi網頁版、Facebook IM。

長連接:在頁面里嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設為對一個長連接的請求或是採用xhr請求,伺服器端就能源源不斷地往客戶端輸入數據。  優點:消息即時到達,不發無用請求;管理起來也相對便。  缺點:伺服器維護一個長連接會增加開銷。  實例:Gmail聊天

Flash Socket:在頁面中內嵌入一個使用了Socket類的 Flash 程式JavaScript通過調用此Flash程式提供的Socket介面與伺服器端的Socket介面進行通信,JavaScript在收到伺服器端傳送的信息後控制頁面的顯示。  優點:實現真正的即時通信,而不是偽即時。  缺點:客戶端必須安裝Flash插件;非HTTP協議,無法自動穿越防火牆。  實例:網路互動游戲。

Websocket:
WebSocket是HTML5開始提供的一種瀏覽器與伺服器間進行全雙工通訊的網路技術。依靠這種技術可以實現客戶端和伺服器端的長連接,雙向實時通信。
特點:
事件驅動
非同步
使用ws或者wss協議的客戶端socket

能夠實現真正意義上的推送功能

缺點:

少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別。

三、WebSocket客戶端

websocket允許通過JavaScript建立與遠程伺服器的連接,從而實現客戶端與伺服器間雙向的通信。在websocket中有兩個方法:  
    1、send() 向遠程伺服器發送數據
    2、close() 關閉該websocket鏈接
  websocket同時還定義了幾個監聽函數    
    1、onopen 當網路連接建立時觸發該事件
    2、onerror 當網路發生錯誤時觸發該事件
    3、onclose 當websocket被關閉時觸發該事件
    4、onmessage 當websocket接收到伺服器發來的消息的時觸發的事件,也是通信中最重要的一個監聽事件。msg.data
  websocket還定義了一個readyState屬性,這個屬性可以返回websocket所處的狀態:
    1、CONNECTING(0) websocket正嘗試與伺服器建立連接
    2、OPEN(1) websocket與伺服器已經建立連接
    3、CLOSING(2) websocket正在關閉與伺服器的連接
    4、CLOSED(3) websocket已經關閉了與伺服器的連接

  websocket的url開頭是ws,如果需要ssl加密可以使用wss,當我們調用websocket的構造方法構建一個websocket對象(new WebSocket(url))的之後,就可以進行即時通信了。

<!DOCTYPE html>
<html>

    <head>
        <meta name="viewport" content="width=device-width" />
        <title>WebSocket 客戶端</title>
    </head>

    <body>
        <div>
            <input type="button" id="btnConnection" value="連接" />
            <input type="button" id="btnClose" value="關閉" />
            <input type="button" id="btnSend" value="發送" />
        </div>
        <script src="js/jquery-1.11.1.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            var socket;
            if(typeof(WebSocket) == "undefined") {
                alert("您的瀏覽器不支持WebSocket");
                return;
            }

            $("#btnConnection").click(function() {
                //實現化WebSocket對象,指定要連接的伺服器地址與埠
                socket = new WebSocket("ws://127.0.0.1:8080/ProjectName/ws/張三");
                //打開事件
                socket.onopen = function() {
                    alert("Socket 已打開");
                    //socket.send("這是來自客戶端的消息" + location.href + new Date());
                };
                //獲得消息事件
                socket.onmessage = function(msg) {
                    alert(msg.data);
                };
                //關閉事件
                socket.onclose = function() {
                    alert("Socket已關閉");
                };
                //發生了錯誤事件
                socket.onerror = function() {
                    alert("發生了錯誤");
                }
            });
            
            //發送消息
            $("#btnSend").click(function() {
                socket.send("這是來自客戶端的消息" + location.href + new Date());
            });
            
            //關閉
            $("#btnClose").click(function() {
                socket.close();
            });
        </script>
    </body>

</html>

四、WebSocket伺服器端

JSR356定義了WebSocket的規範,Tomcat7中實現了該標準。JSR356 的 WebSocket 規範使用 javax.websocket.*的 API,可以將一個普通 Java 對象(POJO)使用 @ServerEndpoint 註釋作為 WebSocket 伺服器的端點。

@ServerEndpoint("/push")
 public class EchoEndpoint {

 @OnOpen
 public void onOpen(Session session) throws IOException {
 //以下代碼省略...
 }
 
 @OnMessage
 public String onMessage(String message) {
 //以下代碼省略...
 }

 @Message(maxMessageSize=6)
 public void receiveMessage(String s) {
 //以下代碼省略...
 } 

 @OnError
 public void onError(Throwable t) {
 //以下代碼省略...
 }
 
 @OnClose
 public void onClose(Session session, CloseReason reason) {
 //以下代碼省略...
 } 
 
 }

上面簡潔代碼即建立了一個WebSocket的服務端,@ServerEndpoint("/push")的annotation註釋端點表示將WebSocket服務端運行在ws://[Server端IP或功能變數名稱]:[Server埠]/項目/push的訪問端點,客戶端瀏覽器已經可以對WebSocket客戶端API發起HTTP長連接了。
使用ServerEndpoint註釋的類必須有一個公共的無參數構造函數,@onMessage註解的Java方法用於接收傳入的WebSocket信息,這個信息可以是文本格式,也可以是二進位格式。
OnOpen在這個端點一個新的連接建立時被調用。參數提供了連接的另一端的更多細節。Session表明兩個WebSocket端點對話連接的另一端,可以理解為類似HTTPSession的概念。
OnClose在連接被終止時調用。參數closeReason可封裝更多細節,如為什麼一個WebSocket連接關閉。
更高級的定製如@Message註釋,MaxMessageSize屬性可以被用來定義消息位元組最大限制,在示常式序中,如果超過6個位元組的信息被接收,就報告錯誤和連接關閉。

package action;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

//ws://127.0.0.1:8087/Demo1/ws/張三
@ServerEndpoint("/ws/{user}")
public class WSServer {
    private String currentUser;
    
    //連接打開時執行
    @OnOpen
    public void onOpen(@PathParam("user") String user, Session session) {
        currentUser = user;
        System.out.println("Connected ... " + session.getId());
    }

    //收到消息時執行
    @OnMessage
    public String onMessage(String message, Session session) {
        System.out.println(currentUser + ":" + message);
        return currentUser + ":" + message;
    }

    //連接關閉時執行
    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        System.out.println(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }

    //連接錯誤時執行
    @OnError
    public void onError(Throwable t) {
        t.printStackTrace();
    }
}

url中的字元張三是的路徑參數,響應請求的方法將自動映射。

五、測試運行

六、小結與消息推送框架

 Socket在應用程式間通信被廣泛使用,如果需要相容低版本的瀏覽器,建議使用反向ajax或長鏈接實現;如果純移動端或不需考慮非現代瀏覽器則可以直接使用websocket。Flash實現推送消息的方法不建議使用,因為依賴插件且手機端支持不好。關於反向ajax也有一些封裝好的插件如“Pushlet”

6.1、開源Java消息推送框架 Pushlet

Pushlet 是一個開源的 Comet 框架,Pushlet 使用了觀察者模型:客戶端發送請求,訂閱感興趣的事件;伺服器端為每個客戶端分配一個會話 ID 作為標記,事件源會把新產生的事件以多播的方式發送到訂閱者的事件隊列里。

源碼地址:https://github.com/wjw465150/Pushlet

Pushlet是一種comet實現:在Servlet機制下,數據從server端的Java對象直接推送(push)到(動態)HTML頁面,而無需任何Javaapplet或者插件的幫助。它使server端可以周期性地更新client的web頁面,這與傳統的request/response方式相悖。瀏覽器client為相容JavaScript1.4版本以上的瀏覽器(如InternetExplorer、FireFox),並使用JavaScript/DynamicHTML特性。而底層實現使用一個servlet通過Http連接到JavaScript所在的瀏覽器,並將數據推送到後者。

6.2、開源DotNet消息推送框架SignalR

SignalR是一個ASP .NET下的類庫,可以在ASP .NET的Web項目中實現實時通信。在Web網頁與伺服器端間建立Socket連接,當WebSockets可用時(即瀏覽器支持Html5)SignalR使用WebSockets,當不支持時SignalR將使用長輪詢來保證達到相同效果。

官網:http://signalr.net/

源碼:https://github.com/SignalR/SignalR

 

七、代碼下載

7.1、Java實現的伺服器端代碼與客戶端代碼下載

點擊下載伺服器端代碼

點擊下載客戶端代碼

7.2、DotNet伺服器端手動連接實現代碼下載

點擊下載DotNet伺服器端手動連接實現代碼

7.3、DotNet下使用SuperWebSocket三方庫實現代碼下載

點擊下載DotNet下使用SuperWebSocket三方庫實現代碼

參照:http://www.cnblogs.com/best


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • XML(Extensible Markup Language),即可擴展的標記語言,它是 SGML(標準通用標記語言)的一個子集,xml文件的主要作用是在於作為程式的配置文件來時用,其他還包括作為不同語言間的數據傳遞以及可以作為一個小型的資料庫存在,XML文件作為一種標記語言,和HTML(Hyper ...
  • 搬運工 頭:header 內容:content/containe 尾:footer 導航:nav 側欄:sidebar 欄目:column 頁面外圍控制整體佈局寬度:wrapper 左右中:left right center 登錄條:loginbar 標誌:logo 廣告:banner 頁面主體:m ...
  • html: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>列表渲染</title></head><body> <!-- v-for可以將一組數組渲染到列表當中 --> <!-- 以item in items的形 ...
  • 為期半個月的項目實踐開發,已完整告一段落,團隊小組獲得第一名,辛苦總算沒有白費,想起有一天晚上,整個小組的人,聯調到12點才從公司回去,真是心酸。這裡總結一下,項目過程中遇到的問題 和感悟。哈哈,放張集體照。嘿嘿,項目所有的不同的team的小伙伴,一群優秀的小伙伴(大多都來自高校211,985)麽麽 ...
  • Special Characters #Latin-1 entity set for HTML capital O, slash #Latin Extended-A #Latin Extended-B #Spacing Modifier Letters Greek Punctuation Gener ...
  • 很多時候頁面都需要一個或者多個小型三角形!多數人直接用PS扣個圖片 下麵用CSS簡單畫幾個最終效果如下圖 ...
  • 提升指定樣式規則的應用優先權。 IE6及以下瀏覽器有個比較顯式的支持問題存在,!important在同一條規則集里不生效。請看下述代碼: 示例代碼: div { color: #f00 !important; color: #000; } 在上述代碼中,IE6及以下瀏覽器div的文本顏色為#000, ...
  • <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #big { height: 800px; width: 800px; background-color: #00 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...