欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WebSocket簡(jiǎn)介與消息推送

 更新時(shí)間:2021年12月16日 15:08:16   作者:張果  
這篇文章介紹了WebSocket簡(jiǎn)介與消息推送,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

B/S結(jié)構(gòu)的軟件項(xiàng)目中有時(shí)客戶端需要實(shí)時(shí)的獲得服務(wù)器消息,但默認(rèn)HTTP協(xié)議只支持請(qǐng)求響應(yīng)模式,這樣做可以簡(jiǎn)化Web服務(wù)器,減少服務(wù)器的負(fù)擔(dān),加快響應(yīng)速度,因?yàn)榉?wù)器不需要與客戶端長(zhǎng)時(shí)間建立一個(gè)通信鏈接,但不容易直接完成實(shí)時(shí)的消息推送功能,如聊天室、后臺(tái)信息提示、實(shí)時(shí)更新數(shù)據(jù)等功能,但通過polling、Long polling、長(zhǎng)連接、Flash Socket以及HTML5中定義的WebSocket能完成該功能需要。

一、Socket簡(jiǎn)介

Socket又稱"套接字",應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。Socket的英文原義是“孔”或“插座”,作為UNIX的進(jìn)程通信機(jī)制。Socket可以實(shí)現(xiàn)應(yīng)用程序間網(wǎng)絡(luò)通信。

Socket可以使用TCP/IP協(xié)議或UDP協(xié)議。

TCP/IP協(xié)議

TCP/IP協(xié)議是目前應(yīng)用最為廣泛的協(xié)議,是構(gòu)成Internet國際互聯(lián)網(wǎng)協(xié)議的最為基礎(chǔ)的協(xié)議,由TCP和IP協(xié)議組成:

TCP協(xié)議:面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,負(fù)責(zé)數(shù)據(jù)的可靠性傳輸?shù)膯栴}。

IP協(xié)議:用于報(bào)文交換網(wǎng)絡(luò)的一種面向數(shù)據(jù)的協(xié)議,主要負(fù)責(zé)給每臺(tái)網(wǎng)絡(luò)設(shè)備一個(gè)網(wǎng)絡(luò)地址,保證數(shù)據(jù)傳輸?shù)秸_的目的地。

UDP協(xié)議

UDP特點(diǎn):無連接、不可靠、基于報(bào)文的傳輸層協(xié)議,優(yōu)點(diǎn)是發(fā)送后不用管,速度比TCP快。

二、WebSocket簡(jiǎn)介與消息推送

B/S架構(gòu)的系統(tǒng)多使用HTTP協(xié)議,HTTP協(xié)議的特點(diǎn):

  • 1 無狀態(tài)協(xié)議
  • 2 用于通過 Internet 發(fā)送請(qǐng)求消息和響應(yīng)消息
  • 3 使用端口接收和發(fā)送消息,默認(rèn)為80端口

底層通信還是使用Socket完成。

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

雙向通信與消息推送

輪詢:客戶端定時(shí)向服務(wù)器發(fā)送Ajax請(qǐng)求,服務(wù)器接到請(qǐng)求后馬上返回響應(yīng)信息并關(guān)閉連接。 優(yōu)點(diǎn):后端程序編寫比較容易。 缺點(diǎn):請(qǐng)求中有大半是無用,浪費(fèi)帶寬和服務(wù)器資源。 實(shí)例:適于小型應(yīng)用。

長(zhǎng)輪詢:客戶端向服務(wù)器發(fā)送Ajax請(qǐng)求,服務(wù)器接到請(qǐng)求后hold住連接,直到有新消息才返回響應(yīng)信息并關(guān)閉連接,客戶端處理完響應(yīng)信息后再向服務(wù)器發(fā)送新的請(qǐng)求。 優(yōu)點(diǎn):在無消息的情況下不會(huì)頻繁的請(qǐng)求,耗費(fèi)資小。 缺點(diǎn):服務(wù)器hold連接會(huì)消耗資源,返回?cái)?shù)據(jù)順序無保證,難于管理維護(hù)。Comet異步的ashx, 實(shí)例:WebQQ、Hi網(wǎng)頁版、Facebook IM。

長(zhǎng)連接:在頁面里嵌入一個(gè)隱蔵iframe,將這個(gè)隱蔵iframe的src屬性設(shè)為對(duì)一個(gè)長(zhǎng)連接的請(qǐng)求或是采用xhr請(qǐng)求,服務(wù)器端就能源源不斷地往客戶端輸入數(shù)據(jù)。 優(yōu)點(diǎn):消息即時(shí)到達(dá),不發(fā)無用請(qǐng)求;管理起來也相對(duì)便。 缺點(diǎn):服務(wù)器維護(hù)一個(gè)長(zhǎng)連接會(huì)增加開銷。 實(shí)例:Gmail聊天

Flash Socket:在頁面中內(nèi)嵌入一個(gè)使用了Socket類的 Flash 程序JavaScript通過調(diào)用此Flash程序提供的Socket接口與服務(wù)器端的Socket接口進(jìn)行通信,JavaScript在收到服務(wù)器端傳送的信息后控制頁面的顯示。 優(yōu)點(diǎn):實(shí)現(xiàn)真正的即時(shí)通信,而不是偽即時(shí)。 缺點(diǎn):客戶端必須安裝Flash插件;非HTTP協(xié)議,無法自動(dòng)穿越防火墻。 實(shí)例:網(wǎng)絡(luò)互動(dòng)游戲。

Websocket:

WebSocket是HTML5開始提供的一種瀏覽器與服務(wù)器間進(jìn)行全雙工通訊的網(wǎng)絡(luò)技術(shù)。依靠這種技術(shù)可以實(shí)現(xiàn)客戶端和服務(wù)器端的長(zhǎng)連接,雙向?qū)崟r(shí)通信。

特點(diǎn):

事件驅(qū)動(dòng)

異步

使用ws或者wss協(xié)議的客戶端socket

能夠?qū)崿F(xiàn)真正意義上的推送功能

缺點(diǎn):

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

三、WebSocket客戶端

websocket允許通過JavaScript建立與遠(yuǎn)程服務(wù)器的連接,從而實(shí)現(xiàn)客戶端與服務(wù)器間雙向的通信。在websocket中有兩個(gè)方法:  

  • 1、send() 向遠(yuǎn)程服務(wù)器發(fā)送數(shù)據(jù)
  • 2、close() 關(guān)閉該websocket鏈接

websocket同時(shí)還定義了幾個(gè)監(jiān)聽函數(shù)    

  • 1、onopen 當(dāng)網(wǎng)絡(luò)連接建立時(shí)觸發(fā)該事件
  • 2、onerror 當(dāng)網(wǎng)絡(luò)發(fā)生錯(cuò)誤時(shí)觸發(fā)該事件
  • 3、onclose 當(dāng)websocket被關(guān)閉時(shí)觸發(fā)該事件
  • 4、onmessage 當(dāng)websocket接收到服務(wù)器發(fā)來的消息的時(shí)觸發(fā)的事件,也是通信中最重要的一個(gè)監(jiān)聽事件。msg.data

websocket還定義了一個(gè)readyState屬性,這個(gè)屬性可以返回websocket所處的狀態(tài):

  • 1、CONNECTING(0) websocket正嘗試與服務(wù)器建立連接
  • 2、OPEN(1) websocket與服務(wù)器已經(jīng)建立連接
  • 3、CLOSING(2) websocket正在關(guān)閉與服務(wù)器的連接
  • 4、CLOSED(3) websocket已經(jīng)關(guān)閉了與服務(wù)器的連接

websocket的url開頭是ws,如果需要ssl加密可以使用wss,當(dāng)我們調(diào)用websocket的構(gòu)造方法構(gòu)建一個(gè)websocket對(duì)象(new WebSocket(url))的之后,就可以進(jìn)行即時(shí)通信了。

<!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="關(guān)閉" />
            <input type="button" id="btnSend" value="發(fā)送" />
        </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() {
                //實(shí)現(xiàn)化WebSocket對(duì)象,指定要連接的服務(wù)器地址與端口
                socket = new WebSocket("ws://192.168.1.2:8888");
                //打開事件
                socket.onopen = function() {
                    alert("Socket 已打開");
                    //socket.send("這是來自客戶端的消息" + location.href + new Date());
                };
                //獲得消息事件
                socket.onmessage = function(msg) {
                    alert(msg.data);
                };
                //關(guān)閉事件
                socket.onclose = function() {
                    alert("Socket已關(guān)閉");
                };
                //發(fā)生了錯(cuò)誤事件
                socket.onerror = function() {
                    alert("發(fā)生了錯(cuò)誤");
                }
            });
            
            //發(fā)送消息
            $("#btnSend").click(function() {
                socket.send("這是來自客戶端的消息" + location.href + new Date());
            });
            
            //關(guān)閉
            $("#btnClose").click(function() {
                socket.close();
            });
        </script>
    </body>

</html>

四、WebSocket服務(wù)器端

JSR356定義了WebSocket的規(guī)范,Tomcat7中實(shí)現(xiàn)了該標(biāo)準(zhǔn)。JSR356 的 WebSocket 規(guī)范使用 javax.websocket.*的 API,可以將一個(gè)普通 Java 對(duì)象(POJO)使用 @ServerEndpoint 注釋作為 WebSocket 服務(wù)器的端點(diǎn)。

@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) {
 //以下代碼省略...
 } 
 
 }

上面簡(jiǎn)潔代碼即建立了一個(gè)WebSocket的服務(wù)端,@ServerEndpoint("/push")的annotation注釋端點(diǎn)表示將WebSocket服務(wù)端運(yùn)行在ws://[Server端IP或域名]:[Server端口]/項(xiàng)目/push的訪問端點(diǎn),客戶端瀏覽器已經(jīng)可以對(duì)WebSocket客戶端API發(fā)起HTTP長(zhǎng)連接了。

使用ServerEndpoint注釋的類必須有一個(gè)公共的無參數(shù)構(gòu)造函數(shù),@onMessage注解的Java方法用于接收傳入的WebSocket信息,這個(gè)信息可以是文本格式,也可以是二進(jìn)制格式。

OnOpen在這個(gè)端點(diǎn)一個(gè)新的連接建立時(shí)被調(diào)用。參數(shù)提供了連接的另一端的更多細(xì)節(jié)。Session表明兩個(gè)WebSocket端點(diǎn)對(duì)話連接的另一端,可以理解為類似HTTPSession的概念。

OnClose在連接被終止時(shí)調(diào)用。參數(shù)closeReason可封裝更多細(xì)節(jié),如為什么一個(gè)WebSocket連接關(guān)閉。

更高級(jí)的定制如@Message注釋,MaxMessageSize屬性可以被用來定義消息字節(jié)最大限制,在示例程序中,如果超過6個(gè)字節(jié)的信息被接收,就報(bào)告錯(cuò)誤和連接關(guān)閉。

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;
    
    //連接打開時(shí)執(zhí)行
    @OnOpen
    public void onOpen(@PathParam("user") String user, Session session) {
        currentUser = user;
        System.out.println("Connected ... " + session.getId());
    }

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

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

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

url中的字符張三是的路徑參數(shù),響應(yīng)請(qǐng)求的方法將自動(dòng)映射。

五、測(cè)試運(yùn)行

六、小結(jié)與消息推送框架

Socket在應(yīng)用程序間通信被廣泛使用,如果需要兼容低版本的瀏覽器,建議使用反向ajax或長(zhǎng)鏈接實(shí)現(xiàn);如果純移動(dòng)端或不需考慮非現(xiàn)代瀏覽器則可以直接使用websocket。Flash實(shí)現(xiàn)推送消息的方法不建議使用,因?yàn)橐蕾嚥寮沂謾C(jī)端支持不好。關(guān)于反向ajax也有一些封裝好的插件如“Pushlet”

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

Pushlet 是一個(gè)開源的 Comet 框架,Pushlet 使用了觀察者模型:客戶端發(fā)送請(qǐng)求,訂閱感興趣的事件;服務(wù)器端為每個(gè)客戶端分配一個(gè)會(huì)話 ID 作為標(biāo)記,事件源會(huì)把新產(chǎn)生的事件以多播的方式發(fā)送到訂閱者的事件隊(duì)列里。

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

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

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

SignalR是一個(gè)ASP .NET下的類庫,可以在ASP .NET的Web項(xiàng)目中實(shí)現(xiàn)實(shí)時(shí)通信。在Web網(wǎng)頁與服務(wù)器端間建立Socket連接,當(dāng)WebSockets可用時(shí)(即瀏覽器支持Html5)SignalR使用WebSockets,當(dāng)不支持時(shí)SignalR將使用長(zhǎng)輪詢來保證達(dá)到相同效果。

官網(wǎng):http://signalr.net/

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

七、代碼下載

7.1、Java實(shí)現(xiàn)的服務(wù)器端代碼與客戶端代碼下載

點(diǎn)擊下載服務(wù)器端代碼

點(diǎn)擊下載客戶端代碼

7.2、DotNet服務(wù)器端手動(dòng)連接實(shí)現(xiàn)代碼下載

點(diǎn)擊下載DotNet服務(wù)器端手動(dòng)連接實(shí)現(xiàn)代碼

7.3、DotNet下使用SuperWebSocket三方庫實(shí)現(xiàn)代碼下載

點(diǎn)擊下載DotNet下使用SuperWebSocket三方庫實(shí)現(xiàn)代碼

到此這篇關(guān)于WebSocket簡(jiǎn)介與消息推送的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • springmvc—handlermapping三種映射方式

    springmvc—handlermapping三種映射方式

    這篇文章主要介紹了springmvc—handlermapping三種映射方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringMVC一步到位精通攔截器

    SpringMVC一步到位精通攔截器

    攔截器(Interceptor)是一種動(dòng)態(tài)攔截方法調(diào)用的機(jī)制,在SpringMVC中動(dòng)態(tài)攔截控制器方法的執(zhí)行。本文將詳細(xì)講講SpringMVC中攔截器的概念及入門案例,感興趣的可以嘗試一下
    2022-12-12
  • Spring boot @RequestBody數(shù)據(jù)傳遞過程詳解

    Spring boot @RequestBody數(shù)據(jù)傳遞過程詳解

    這篇文章主要介紹了Spring boot @RequestBody數(shù)據(jù)傳遞過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 解決Java變異出現(xiàn)錯(cuò)誤No enclosing instance of type XXX is accessible

    解決Java變異出現(xiàn)錯(cuò)誤No enclosing instance of type XXX is accessible

    這牌你文章主要給大家分享解決Java變異出現(xiàn)錯(cuò)誤,具體的饑餓絕方案請(qǐng)看下面文章的內(nèi)容,需要的朋友可以參考一下,希望能幫助到你
    2021-09-09
  • SpringBoot框架集成ElasticSearch實(shí)現(xiàn)過程示例詳解

    SpringBoot框架集成ElasticSearch實(shí)現(xiàn)過程示例詳解

    這篇文章主要為大家介紹了SpringBoot如何集成ElasticSearch的實(shí)現(xiàn)過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • SpringBoot路徑映射實(shí)現(xiàn)過程圖解

    SpringBoot路徑映射實(shí)現(xiàn)過程圖解

    這篇文章主要介紹了SpringBoot路徑映射實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • MyBatis 配置之集合的嵌套方式

    MyBatis 配置之集合的嵌套方式

    這篇文章主要介紹了MyBatis 配置之集合的嵌套方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java微信開發(fā)第二步 獲取消息和回復(fù)消息

    java微信開發(fā)第二步 獲取消息和回復(fù)消息

    這篇文章主要為大家分享java微信開發(fā)的第二步,如何獲取消息和回復(fù)消息,感興趣的小伙伴們可以參考一下
    2016-05-05
  • java代理模式(靜態(tài)代理、動(dòng)態(tài)代理、cglib代理)

    java代理模式(靜態(tài)代理、動(dòng)態(tài)代理、cglib代理)

    代理(Proxy)是一種設(shè)計(jì)模式,提供了對(duì)目標(biāo)對(duì)象另外的訪問方式;這篇文章主要介紹了Java 中的三種代理模式,需要的朋友可以參考下,希望能給你帶來幫助
    2021-07-07
  • 詳談java 堆區(qū)、方法區(qū)和棧區(qū)

    詳談java 堆區(qū)、方法區(qū)和棧區(qū)

    下面小編就為大家?guī)硪黄斦刯ava 堆區(qū)、方法區(qū)和棧區(qū)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05

最新評(píng)論