国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

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

發(fā)布時(shí)間:2021-07-17 21:51 來(lái)源:腳本之家 閱讀:0 作者:北海道戀人 欄目: 編程語(yǔ)言 歡迎投稿:712375056

目錄

一、WebSocket簡(jiǎn)介

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

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

1.1 WebSocket協(xié)議

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

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ù)端響應:

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

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

1.2 WebSocket支持的消息類(lèi)型

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

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

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

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

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

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

2.1 生命周期方法

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

@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ù)類(lèi)最多可以有三個(gè)OnMessage注解,每個(gè)消息類(lèi)型分別使用一種方法:Text、Binary、Pong

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

有時(shí)在程序中我們可能需要在連接中維護一些用戶(hù)參數,WebSocket也提供了這樣的服務(wù)
Session.getUserProperties獲取用戶(hù)參數信息
如果要存儲所有連接的客戶(hù)端共有的信息,可以使用靜態(tài)變量,但是需要用戶(hù)保證對數據的線(xiàn)程安全訪(fǎng)問(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 數據格式的編碼與解碼

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

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

使用方法:

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

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)類(lèi)注解中添加該Encoder

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

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

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

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

Decoder

實(shí)現Decoder以將WebSocket消息轉換為Java對象

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

使用方法

與Encoder類(lèi)似

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

1、編寫(xiě)Decoder類(lèi),對收到消息類(lèi)型的不同進(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)類(lèi)中添加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詳解內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

日韩人妻无码精品专区| 波多野结衣绝顶大高潮| 一个人看片BD高清最新| 国产精品无码素人福利免费| 国产成人一区二区三区免费视频| 久久九九有精品国产|