最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

教你如何使用Java實現(xiàn)WebSocket

 更新時間:2023年06月01日 10:15:54   作者:今昔在  
這篇文章主要介紹了教你如何使用Java實現(xiàn)WebSocket問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一、WebSocket簡介

WebSocket協(xié)議通過在客戶端和服務端之間提供全雙工通信來進行Web和服務器的交互功能。

在WebSocket應用程序中,服務器發(fā)布WebSocket端點,客戶端使用url連接到服務器。

建立連接后,服務器和客戶端就可以互相發(fā)送消息。

客戶端通常連接到一臺服務器,服務器接受多個客戶端的連接。

1.1 WebSocket協(xié)議

WebSocket協(xié)議有兩個部分:握手和傳輸。

客戶端通過向服務端URL發(fā)送握手請求來建立連接。

握手與現(xiàn)有的基于HTTP的基礎結(jié)構(gòu)相兼容。

Web服務器將其解釋為升級版的HTTP連接請求。

一個客戶端建立連接的握手請求:

GET /path/to/websocket/endpoint HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
Origin: http://localhost
Sec-WebSocket-Version: 13

一個服務端響應:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

從上面的請求和響應中可以看出來,一個WebSocket連接的建立,需要客戶端和服務端維護一個Key來作為該連接的連接憑證。

客戶端向服務端發(fā)送WebSocketKey,服務器根據(jù)WebSocketKey生成WebSocketAccept返回給客戶端,客戶端對WebSocketKey的值再進行相同的操作,如果與服務器返回的Accept的值相匹配,就表示握手成功。

握手之后客戶端與服務端就互相發(fā)送消息。

1.2 WebSocket支持的消息類型

WebSocket支持文本消息(UTF-8編碼)和二進制消息。

WebSocket的控制消息由Close、Ping、Pong組成。

ping和pong也有可能包含應用程序信息。

webSocket端點具有如下的URI形式表示:

ws://host:port/path?query
wss://host:port/path?query

ws代表未加密的連接,默認端口是80

wss代表加密的連接,默認端口是443

  • path:表示服務器內(nèi)端點的位置
  • query:路徑參數(shù)信息

二、創(chuàng)建一個WebSocket程序

創(chuàng)建和部署WebSocket端點的過程如下:

  • 1、創(chuàng)建一個端點類
  • 2、實現(xiàn)端點的生命周期方法
  • 3、將業(yè)務邏輯添加到端點
  • 4、將端點部署到Web應用程序中

**注意:**與Servlet相反,WebSocket端點類會被實例化多次,容器針對與其部署的URI的每個連接都創(chuàng)建一個實例。

每個實例都與一個連接相關聯(lián)。

因為在任何時間都只有一個線程執(zhí)行端點實例的代碼,所以有助于保持每個連接的用戶狀態(tài)簡化開發(fā)。

2.1 生命周期方法

EndPoint類中定義了三個生命周期方法:onOpen、onClose、onError

使用注解方式創(chuàng)建服務類

@ServerEndpoint("/echo")
public class EchoEndpoint {
   @OnMessage
   public void onMessage(Session session, String msg) {
      try {
         session.getBasicRemote().sendText(msg);
      } catch (IOException e) { ... }
   }
}

2.2 業(yè)務邏輯方法

@ServerEndpoint("/receive")
public class ReceiveEndpoint {
   @OnMessage
   public void textMessage(Session session, String msg) {
      System.out.println("Text message: " + msg);
   }
   @OnMessage
   public void binaryMessage(Session session, ByteBuffer msg) {
      System.out.println("Binary message: " + msg.toString());
   }
   @OnMessage
   public void pongMessage(Session session, PongMessage msg) {
      System.out.println("Pong message: " + 
                          msg.getApplicationData().toString());
   }
}

注意:一個服務類最多可以有三個OnMessage注解,每個消息類型分別使用一種方法:Text、Binary、Pong

2.3 維護客戶狀態(tài)

有時在程序中我們可能需要在連接中維護一些用戶參數(shù),WebSocket也提供了這樣的服務

Session.getUserProperties獲取用戶參數(shù)信息

如果要存儲所有連接的客戶端共有的信息,可以使用靜態(tài)變量,但是需要用戶保證對數(shù)據(jù)的線程安全訪問。

@ServerEndpoint("/delayedecho")
public class DelayedEchoEndpoint {
   @OnOpen
   public void open(Session session) {
      session.getUserProperties().put("previousMsg", " ");
   }
   @OnMessage
   public void message(Session session, String msg) {
      String prev = (String) session.getUserProperties()
                                    .get("previousMsg");
      session.getUserProperties().put("previousMsg", msg);
      try {
         session.getBasicRemote().sendText(prev);
      } catch (IOException e) { ... }
   }
}

2.4 數(shù)據(jù)格式的編碼與解碼

由于客戶端和服務端交互可能涉及數(shù)據(jù)格式的轉(zhuǎn)換,所以提供了Decoder和Encoder的方式解決。

同時由于WebSocket的@Message注解只能有一個用來傳輸Text信息或Binary信息,所以要進行最常用的Json->entity轉(zhuǎn)換解析就需要該方法

  • Encoder

Encoder.Text 用于文本消息Encoder.Binary 用于二進制消息

使用方法:

1、創(chuàng)建編解碼類

public class MessageATextEncoder implements Encoder.Text<MessageA> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public String encode(MessageA msgA) throws EncodeException {
      // Access msgA's properties and convert to JSON text...
      return msgAJsonString;
   }
}

2、在端點類注解中添加該Encoder

@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class }
)
public class EncEndpoint { ... }

3、這時候就可以發(fā)送MessageA和MessageB兩種類型的Text數(shù)據(jù)

MessageA msgA = new MessageA(...);
MessageB msgB = new MessageB(...);
session.getBasicRemote.sendObject(msgA);
session.getBasicRemote.sendObject(msgB);

注意:webSocket會自動尋找使用哪種編碼器,所以發(fā)送數(shù)據(jù)統(tǒng)一使用sendObject即可

  • Decoder

實現(xiàn)Decoder以將WebSocket消息轉(zhuǎn)換為Java對象

  • Decoder.Text 用于文本消息
  • Decoder.Binary 用于二進制消息

使用方法

與Encoder類似

注意:與Encoder不同,Decoder最多可以指定一個Binary和一個Text類型的Decoder,如果有兩種以上的Java類型作為文本消息進行發(fā)送和接收需要進行定義處理??梢允苟鄠€消息繼承一個公共的消息父類

1、編寫Decoder類,對收到消息類型的不同進行不同的解碼

public class MessageTextDecoder implements Decoder.Text<Message> {
   @Override
   public void init(EndpointConfig ec) { }
   @Override
   public void destroy() { }
   @Override
   public Message decode(String string) throws DecodeException {
      // Read message...
      if ( /* message is an A message */ )
         return new MessageA(...);
      else if ( /* message is a B message */ )
         return new MessageB(...);
   }
   @Override
   public boolean willDecode(String string) {
      // Determine if the message can be converted into either a
      // MessageA object or a MessageB object...
      return canDecode;
   }
}

2、在端點類中添加decoders={MessageDecoder.class}

@ServerEndpoint(
   value = "/myendpoint",
   encoders = { MessageATextEncoder.class, MessageBTextEncoder.class },
   decoders = { MessageTextDecoder.class }
)
public class EncDecEndpoint { ... }

3、在@OnMessage方法中使用

@OnMessage
public void message(Session session, Message msg) {
   if (msg instanceof MessageA) {
      // We received a MessageA object...
   } else if (msg instanceof MessageB) {
      // We received a MessageB object...
   }
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Lucene實現(xiàn)索引和查詢的實例講解

    Lucene實現(xiàn)索引和查詢的實例講解

    下面小編就為大家分享一篇Lucene實現(xiàn)索引和查詢的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Spring中ApplicationEventPublisher發(fā)布訂閱模式的實現(xiàn)

    Spring中ApplicationEventPublisher發(fā)布訂閱模式的實現(xiàn)

    本文主要介紹了Spring中ApplicationEventPublisher發(fā)布訂閱模式的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • spring中在xml配置中加載properties文件的步驟

    spring中在xml配置中加載properties文件的步驟

    這篇文章主要介紹了在spring中如何在xml配置中加載properties文件,本文分步驟給大家介紹在XML配置中加載properties文件的方法,需要的朋友可以參考下
    2023-07-07
  • java接入創(chuàng)藍253短信驗證碼的實例講解

    java接入創(chuàng)藍253短信驗證碼的實例講解

    下面小編就為大家分享一篇java接入創(chuàng)藍253短信驗證碼的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Javadoc標簽和Javadoc注釋規(guī)范說明

    Javadoc標簽和Javadoc注釋規(guī)范說明

    這篇文章主要介紹了Javadoc標簽和Javadoc注釋規(guī)范說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 從架構(gòu)思維角度分析高并發(fā)下冪等性解決方案

    從架構(gòu)思維角度分析高并發(fā)下冪等性解決方案

    冪等(idempotent、idempotence)是一個數(shù)學與計算機學概念,常見于抽象代數(shù)中。?在編程中.一個冪等操作的特點是其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。冪等函數(shù),或冪等方法,是指可以使用相同參數(shù)重復執(zhí)行,并能獲得相同結(jié)果的函數(shù)
    2022-01-01
  • Springboot任務之異步任務的使用詳解

    Springboot任務之異步任務的使用詳解

    今天學習了一個新技能SpringBoot實現(xiàn)異步任務,所以特地整理了本篇文章,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • mybatis 一對多嵌套查詢的實現(xiàn)

    mybatis 一對多嵌套查詢的實現(xiàn)

    本文主要介紹了mybatis 一對多嵌套查詢的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-07-07
  • Java實現(xiàn)用戶管理系統(tǒng)

    Java實現(xiàn)用戶管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)用戶管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • SpringAop日志找不到方法的處理

    SpringAop日志找不到方法的處理

    這篇文章主要介紹了SpringAop日志找不到方法的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論

沾化县| 沧源| 翁牛特旗| 东安县| 班玛县| 堆龙德庆县| 甘肃省| 财经| 遂川县| 湛江市| 德昌县| 德清县| 翁牛特旗| 白河县| 酒泉市| 福鼎市| 二连浩特市| 兴义市| 东乌珠穆沁旗| 资源县| 海林市| 札达县| 济源市| 浦城县| 仪陇县| 门源| 商城县| 波密县| 依安县| 武陟县| 石门县| 阿克| 富宁县| 玛多县| 名山县| 大足县| 雅安市| 怀宁县| 丽水市| 盘锦市| 昭觉县|