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

教你怎么使用Java實(shí)現(xiàn)WebSocket

 更新時(shí)間:2021年05月07日 16:52:46   作者:北海道戀人  
這篇文章主要介紹了教你怎么使用Java WebSocket,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下

一、WebSocket簡(jiǎn)介

WebSocket協(xié)議通過(guò)在客戶端和服務(wù)端之間提供全雙工通信來(lái)進(jìn)行Web和服務(wù)器的交互功能。

在WebSocket應(yīng)用程序中,服務(wù)器發(fā)布WebSocket端點(diǎn),客戶端使用url連接到服務(wù)器。建立連接后,服務(wù)器和客戶端就可以互相發(fā)送消息。客戶端通常連接到一臺(tái)服務(wù)器,服務(wù)器接受多個(gè)客戶端的連接。

1.1 WebSocket協(xié)議

WebSocket協(xié)議有兩個(gè)部分:握手和傳輸。客戶端通過(guò)向服務(wù)端URL發(fā)送握手請(qǐng)求來(lái)建立連接。握手與現(xiàn)有的基于HTTP的基礎(chǔ)結(jié)構(gòu)相兼容。Web服務(wù)器將其解釋為升級(jí)版的HTTP連接請(qǐng)求。
一個(gè)客戶端建立連接的握手請(qǐng)求:

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

一個(gè)服務(wù)端響應(yīng):

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

從上面的請(qǐng)求和響應(yīng)中可以看出來(lái),一個(gè)WebSocket連接的建立,需要客戶端和服務(wù)端維護(hù)一個(gè)Key來(lái)作為該連接的連接憑證。
客戶端向服務(wù)端發(fā)送WebSocketKey,服務(wù)器根據(jù)WebSocketKey生成WebSocketAccept返回給客戶端,客戶端對(duì)WebSocketKey的值再進(jìn)行相同的操作,如果與服務(wù)器返回的Accept的值相匹配,就表示握手成功。握手之后客戶端與服務(wù)端就互相發(fā)送消息。

在這里插入圖片描述

1.2 WebSocket支持的消息類型

WebSocket支持文本消息(UTF-8編碼)和二進(jìn)制消息。WebSocket的控制消息由Close、Ping、Pong組成。ping和pong也有可能包含應(yīng)用程序信息。
webSocket端點(diǎn)具有如下的URI形式表示:

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

ws代表未加密的連接,默認(rèn)端口是80
wss代表加密的連接,默認(rèn)端口是443
path:表示服務(wù)器內(nèi)端點(diǎn)的位置
query:路徑參數(shù)信息

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

創(chuàng)建和部署WebSocket端點(diǎn)的過(guò)程如下:
1、創(chuàng)建一個(gè)端點(diǎn)類
2、實(shí)現(xiàn)端點(diǎn)的生命周期方法
3、將業(yè)務(wù)邏輯添加到端點(diǎn)
4、將端點(diǎn)部署到Web應(yīng)用程序中

注意:與Servlet相反,WebSocket端點(diǎn)類會(huì)被實(shí)例化多次,容器針對(duì)與其部署的URI的每個(gè)連接都創(chuàng)建一個(gè)實(shí)例。每個(gè)實(shí)例都與一個(gè)連接相關(guān)聯(lián)。因?yàn)樵谌魏螘r(shí)間都只有一個(gè)線程執(zhí)行端點(diǎn)實(shí)例的代碼,所以有助于保持每個(gè)連接的用戶狀態(tài)簡(jiǎn)化開發(fā)。

2.1 生命周期方法

EndPoint類中定義了三個(gè)生命周期方法:onOpen、onClose、onError
使用注解方式創(chuàng)建服務(wù)類

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

2.2 業(yè)務(wù)邏輯方法

@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());
   }
}

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

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

有時(shí)在程序中我們可能需要在連接中維護(hù)一些用戶參數(shù),WebSocket也提供了這樣的服務(wù)
Session.getUserProperties獲取用戶參數(shù)信息
如果要存儲(chǔ)所有連接的客戶端共有的信息,可以使用靜態(tài)變量,但是需要用戶保證對(duì)數(shù)據(jù)的線程安全訪問(wèn)。

@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ù)格式的編碼與解碼

由于客戶端和服務(wù)端交互可能涉及數(shù)據(jù)格式的轉(zhuǎn)換,所以提供了Decoder和Encoder的方式解決。
同時(shí)由于WebSocket的@Message注解只能有一個(gè)用來(lái)傳輸Text信息或Binary信息,所以要進(jìn)行最常用的Json->entity轉(zhuǎn)換解析就需要該方法
Encoder

Encoder.Text 用于文本消息Encoder.Binary 用于二進(jìn)制消息

使用方法:

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、在端點(diǎn)類注解中添加該Encoder

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

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

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

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

Decoder

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

  • Decoder.Text 用于文本消息
  • Decoder.Binary 用于二進(jìn)制消息

使用方法

與Encoder類似

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

1、編寫Decoder類,對(duì)收到消息類型的不同進(jìn)行不同的解碼

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、在端點(diǎn)類中添加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...
   }
}

到此這篇關(guān)于教你怎么使用Java WebSocket的文章就介紹到這了,更多相關(guān)Java WebSocket詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用微信小程序+JAVA實(shí)現(xiàn)微信支付的全過(guò)程

    利用微信小程序+JAVA實(shí)現(xiàn)微信支付的全過(guò)程

    微信支付是一種在線支付解決方案,允許用戶通過(guò)微信內(nèi)的支付功能進(jìn)行付款,下面這篇文章主要給大家介紹了關(guān)于利用微信小程序+JAVA實(shí)現(xiàn)微信支付的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • 解決spring security中遇到的問(wèn)題

    解決spring security中遇到的問(wèn)題

    這篇文章主要介紹了解決spring security中遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Java打包ZIP文件的使用

    Java打包ZIP文件的使用

    本文詳細(xì)介紹了如何使用Java語(yǔ)言進(jìn)行ZIP文件的創(chuàng)建、讀取和操作,通過(guò)java.util.zip包和第三方庫(kù),可以高效地處理ZIP文件,并應(yīng)用密碼保護(hù)和注釋等高級(jí)功能,在實(shí)際應(yīng)用中,遵循最佳實(shí)踐可以提高程序的健壯性和安全性
    2025-02-02
  • Springmvc基于fastjson實(shí)現(xiàn)導(dǎo)包及配置文件

    Springmvc基于fastjson實(shí)現(xiàn)導(dǎo)包及配置文件

    這篇文章主要介紹了Springmvc基于fastjson實(shí)現(xiàn)導(dǎo)包及配置文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 淺談Apache Maven ToolChains的使用

    淺談Apache Maven ToolChains的使用

    Maven是java中非常有用和常用的構(gòu)建工具,基本上現(xiàn)在大型的java項(xiàng)目都是Maven和gradle的天下了。本文將介紹Apache Maven ToolChains的使用。
    2021-06-06
  • java方法實(shí)現(xiàn)簡(jiǎn)易ATM功能

    java方法實(shí)現(xiàn)簡(jiǎn)易ATM功能

    這篇文章主要為大家詳細(xì)介紹了用java方法實(shí)現(xiàn)簡(jiǎn)易ATM功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Java設(shè)計(jì)模式之備忘錄模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院

    Java設(shè)計(jì)模式之備忘錄模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院

    我們?cè)诰幊痰臅r(shí)候,經(jīng)常需要保存對(duì)象的中間狀態(tài),當(dāng)需要的時(shí)候,可以恢復(fù)到這個(gè)狀態(tài)。接下來(lái)通過(guò)本文給大家分享java設(shè)計(jì)模式之備忘錄模式,感興趣的的朋友一起看看吧
    2017-08-08
  • SpringBoot集成Redis使用Cache緩存的實(shí)現(xiàn)方法

    SpringBoot集成Redis使用Cache緩存的實(shí)現(xiàn)方法

    SpringBoot通過(guò)配置RedisConfig類和使用Cache注解可以輕松集成Redis實(shí)現(xiàn)緩存,主要包括@EnableCaching開啟緩存,自定義key生成器,改變序列化規(guī)則,以及配置RedisCacheManager,本文為使用SpringBoot與Redis處理緩存提供了詳實(shí)的指導(dǎo)和示例,感興趣的朋友一起看看吧
    2024-10-10
  • Spring Bean初始化和銷毀的三種方式

    Spring Bean初始化和銷毀的三種方式

    這篇文章介紹了Spring框架中Bean的初始化和銷毀的幾種方式,包括實(shí)現(xiàn)InitializingBean接口、使用@PostConstruct注解、自定義init方法以及實(shí)現(xiàn)DisposableBean接口、使用@PreDestroy注解和自定義銷毀方法,需要的朋友可以參考下
    2025-11-11
  • list集合去除重復(fù)對(duì)象的實(shí)現(xiàn)

    list集合去除重復(fù)對(duì)象的實(shí)現(xiàn)

    下面小編就為大家?guī)?lái)一篇list集合去除重復(fù)對(duì)象的實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01

最新評(píng)論

池州市| 武平县| 突泉县| 长顺县| 黑河市| 大竹县| 五峰| 浦江县| 加查县| 呼玛县| 宜黄县| 鄂州市| 什邡市| 荔浦县| 肃北| 岱山县| 嘉鱼县| 开原市| 卓尼县| 平利县| 米泉市| 益阳市| 宣城市| 泾阳县| 革吉县| 中阳县| 土默特右旗| 米脂县| 夏津县| 新蔡县| 禹城市| 台前县| 通许县| 宁波市| 安平县| 云林县| 贵定县| 阳西县| 丰县| 云林县| 鄂尔多斯市|