如何使用Java实现WebSocket(java,websocket,开发技术)

时间:2024-05-05 12:01:08 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

Java可以用来干什么

Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4. 网页开发;5. 企业级应用开发;6. Java大数据开发;7.游戏开发等。

一、WebSocket简介

WebSocket协议通过在客户端和服务端之间提供全双工通信来进行Web和服务器的交互功能。

在WebSocket应用程序中,服务器发布WebSocket端点,客户端使用url连接到服务器。建立连接后,服务器和客户端就可以互相发送消息。客户端通常连接到一台服务器,服务器接受多个客户端的连接。

1.1 WebSocket协议

WebSocket协议有两个部分:握手和传输。客户端通过向服务端URL发送握手请求来建立连接。握手与现有的基于HTTP的基础结构相兼容。Web服务器将其解释为升级版的HTTP连接请求。
一个客户端建立连接的握手请求:

GET/path/to/websocket/endpointHTTP/1.1Host:localhostUpgrade:websocketConnection:UpgradeSec-WebSocket-Key:xqBt3ImNzJbYqRINxEFlkg==Origin:http://localhostSec-WebSocket-Version:13

一个服务端响应:

HTTP/1.1101SwitchingProtocolsUpgrade:websocketConnection:UpgradeSec-WebSocket-Accept:K7DJLdLooIwIG/MOpvWFB3y3FE8=

从上面的请求和响应中可以看出来,一个WebSocket连接的建立,需要客户端和服务端维护一个Key来作为该连接的连接凭证。
客户端向服务端发送WebSocketKey,服务器根据WebSocketKey生成WebSocketAccept返回给客户端,客户端对WebSocketKey的值再进行相同的操作,如果与服务器返回的Accept的值相匹配,就表示握手成功。握手之后客户端与服务端就互相发送消息。

如何使用Java实现WebSocket

1.2 WebSocket支持的消息类型

WebSocket支持文本消息(UTF-8编码)和二进制消息。WebSocket的控制消息由Close、Ping、Pong组成。ping和pong也有可能包含应用程序信息。
webSocket端点具有如下的URI形式表示:

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

ws代表未加密的连接,默认端口是80
wss代表加密的连接,默认端口是443
path:表示服务器内端点的位置
query:路径参数信息

二、创建一个WebSocket程序

创建和部署WebSocket端点的过程如下:
1、创建一个端点类
2、实现端点的生命周期方法
3、将业务逻辑添加到端点
4、将端点部署到Web应用程序中

注意:与Servlet相反,WebSocket端点类会被实例化多次,容器针对与其部署的URI的每个连接都创建一个实例。每个实例都与一个连接相关联。因为在任何时间都只有一个线程执行端点实例的代码,所以有助于保持每个连接的用户状态简化开发。

2.1 生命周期方法

EndPoint类中定义了三个生命周期方法:onOpen、onClose、onError
使用注解方式创建服务类

@ServerEndpoint("/echo")publicclassEchoEndpoint{@OnMessagepublicvoidonMessage(Sessionsession,Stringmsg){try{session.getBasicRemote().sendText(msg);}catch(IOExceptione){...}}}

2.2 业务逻辑方法

@ServerEndpoint("/receive")publicclassReceiveEndpoint{@OnMessagepublicvoidtextMessage(Sessionsession,Stringmsg){System.out.println("Textmessage:"+msg);}@OnMessagepublicvoidbinaryMessage(Sessionsession,ByteBuffermsg){System.out.println("Binarymessage:"+msg.toString());}@OnMessagepublicvoidpongMessage(Sessionsession,PongMessagemsg){System.out.println("Pongmessage:"+msg.getApplicationData().toString());}}

注意:一个服务类最多可以有三个OnMessage注解,每个消息类型分别使用一种方法:Text、Binary、Pong

2.3 维护客户状态

有时在程序中我们可能需要在连接中维护一些用户参数,WebSocket也提供了这样的服务
Session.getUserProperties获取用户参数信息
如果要存储所有连接的客户端共有的信息,可以使用静态变量,但是需要用户保证对数据的线程安全访问。

@ServerEndpoint("/delayedecho")publicclassDelayedEchoEndpoint{@OnOpenpublicvoidopen(Sessionsession){session.getUserProperties().put("previousMsg","");}@OnMessagepublicvoidmessage(Sessionsession,Stringmsg){Stringprev=(String)session.getUserProperties().get("previousMsg");session.getUserProperties().put("previousMsg",msg);try{session.getBasicRemote().sendText(prev);}catch(IOExceptione){...}}}

2.4 数据格式的编码与解码

由于客户端和服务端交互可能涉及数据格式的转换,所以提供了Decoder和Encoder的方式解决。
同时由于WebSocket的@Message注解只能有一个用来传输Text信息或Binary信息,所以要进行最常用的Json->entity转换解析就需要该方法
Encoder

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

使用方法:

1、创建编解码类

publicclassMessageATextEncoderimplementsEncoder.Text<MessageA>{@Overridepublicvoidinit(EndpointConfigec){}@Overridepublicvoiddestroy(){}@OverridepublicStringencode(MessageAmsgA)throwsEncodeException{//AccessmsgA'spropertiesandconverttoJSONtext...returnmsgAJsonString;}}

2、在端点类注解中添加该Encoder

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

3、这时候就可以发送MessageA和MessageB两种类型的Text数据

MessageAmsgA=newMessageA(...);MessageBmsgB=newMessageB(...);session.getBasicRemote.sendObject(msgA);session.getBasicRemote.sendObject(msgB);

注意:webSocket会自动寻找使用哪种编码器,所以发送数据统一使用sendObject即可

Decoder

实现Decoder以将WebSocket消息转换为Java对象

  • Decoder.Text 用于文本消息

  • Decoder.Binary 用于二进制消息

使用方法

与Encoder类似

注意:与Encoder不同,Decoder最多可以指定一个Binary和一个Text类型的Decoder,如果有两种以上的Java类型作为文本消息进行发送和接收需要进行定义处理。可以使多个消息继承一个公共的消息父类

1、编写Decoder类,对收到消息类型的不同进行不同的解码

publicclassMessageTextDecoderimplementsDecoder.Text<Message>{@Overridepublicvoidinit(EndpointConfigec){}@Overridepublicvoiddestroy(){}@OverridepublicMessagedecode(Stringstring)throwsDecodeException{//Readmessage...if(/*messageisanAmessage*/)returnnewMessageA(...);elseif(/*messageisaBmessage*/)returnnewMessageB(...);}@OverridepublicbooleanwillDecode(Stringstring){//Determineifthemessagecanbeconvertedintoeithera//MessageAobjectoraMessageBobject...returncanDecode;}}

2、在端点类中添加decoders={MessageDecoder.class}

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

3、在@OnMessage方法中使用

@OnMessagepublicvoidmessage(Sessionsession,Messagemsg){if(msginstanceofMessageA){//WereceivedaMessageAobject...}elseif(msginstanceofMessageB){//WereceivedaMessageBobject...}}
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:如何使用Java实现WebSocket的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:PHP如何实现局部替换下一篇:

12 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18