SpringBoot——使用WebSocket功能
创始人
2024-05-30 18:28:08
0

springboot自带websocket,通过几个简单的注解就可以实现websocket的功能;

启动类跟普通的springboot一样:

/*** 2023年3月2日下午4:16:57*/
package testspringboot.test7websocket;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;/*** @author XWF**/
@SpringBootApplication
@PropertySource(value = "test7.properties")
public class Test7Main {/*** @param args*/public static void main(String[] args) {SpringApplication.run(Test7Main.class, args);}}

还需要一个websocket的配置类:

/*** 2023年3月2日下午4:26:15*/
package testspringboot.test7websocket;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** @author XWF**/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

配置文件里只配置了一个端口:

主要的逻辑都放到@ServerEndpoint标签注释的类里,类似controller的功能;

可以使用4种注解处理业务:

  • @OnOpen:处理客户端的连接;
  • @OnClose:处理客户端断开;
  • @OnError:处理故障错误;
  • @OnMessage:处理具体消息,有三种消息类型:String类型,ByteBuffer类型,PongMessage类型,同一消息类型类里不能出现多次;

另外可以通过Session对象设置属性或者发送数据,session.getUserProperties()存取属性,session.getBasicRemote()或者session.getAsyncRemote()可以进行同步异步发送数据;

处理类:

/*** 2023年3月2日下午4:27:01*/
package testspringboot.test7websocket;import java.io.IOException;
import java.nio.ByteBuffer;import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.PongMessage;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;import org.springframework.stereotype.Component;/*** @author XWF**/
@Component
@ServerEndpoint(value = "/websockettest/{name}")
public class WebSocketHandler {@OnOpen  public void onOpen(@PathParam("name") String name, Session session) throws IOException {  System.out.println("onOpen:" + name);session.getUserProperties().put("name", name);}@OnClose  public void onClose(@PathParam("name") String name, Session session) throws IOException {System.out.println("onClose:" + name);System.out.println(session.getUserProperties().get("name") + "关闭了");}@OnError  public void onError(Session session, Throwable error) {System.out.println("onERROR");error.printStackTrace();  }@OnMessagepublic void textMessage(Session session, String msg) {System.out.println("收到:" + msg);try {session.getBasicRemote().sendText("hello");} catch (IOException e) {e.printStackTrace();}}@OnMessagepublic void binaryMessage(Session session, ByteBuffer msg) {System.out.println("Binary message: " + msg.toString());}@OnMessagepublic void pongMessage(Session session, PongMessage msg) {System.out.println("Pong message: " + msg.getApplicationData().toString());}}

测试websocket用的Apipost:

连接测试:

发送数据测试:

断开连接:

另外,也可以设置自己的编解码处理自己的消息,实现javax.websocket.Encoder.Text或者javax.websocket.Encoder.Binary接口实现编码器,实现javax.websocket.Decoder.Text或者javax.websocket.Decoder.Binary接口实现解码器,解码器最多两个,一个解码Text一个Binary;

在@ServerEndpoint注解里配置上自己的encoders和decoders就可以实现自定义编解码了;

自定义消息MsgA:

/*** 2023年3月3日下午3:12:47*/
package testspringboot.test7websocket;/*** @author XWF**/
public class MsgA {public int id;public String name;@Overridepublic String toString() {return "MsgA [id=" + id + ", name=" + name + "]";}}

编码器:

/*** 2023年3月3日下午3:14:02*/
package testspringboot.test7websocket;import javax.websocket.EncodeException;
import javax.websocket.Encoder.Text;
import javax.websocket.EndpointConfig;/*** @author XWF**/
public class MsgATextEncoder implements Text{@Overridepublic void init(EndpointConfig endpointConfig) {System.out.println("msga encoder init");}@Overridepublic void destroy() {System.out.println("msga encoder destroy");}// 进行编码操作,将对象编码成string@Overridepublic String encode(MsgA object) throws EncodeException {return object.toString();}}

解码器:

/*** 2023年3月3日下午3:16:52*/
package testspringboot.test7websocket;import javax.websocket.DecodeException;
import javax.websocket.Decoder.Text;
import javax.websocket.EndpointConfig;/*** @author XWF**/
public class MsgATextDecoder implements Text {@Overridepublic void init(EndpointConfig endpointConfig) {System.out.println("msga decoder init");}@Overridepublic void destroy() {System.out.println("msga decoder destroy");}// 进行解码操作,将string解码成需要的对象@Overridepublic MsgA decode(String s) throws DecodeException {MsgA msga = new MsgA();msga.id = Integer.parseInt(s.split(",")[0]);msga.name = s.split(",")[1];return msga;}// 验证消息是否可以解码,返回true可以解码,否则返回false@Overridepublic boolean willDecode(String s) {// 接收格式:id,nameif (s.split(",").length == 2) {try {Integer.parseInt(s.split(",")[0]);} catch (NumberFormatException e) {return false;}return true;} else {return false;}}}

处理类:

/*** 2023年3月3日下午3:07:45*/
package testspringboot.test7websocket;import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;import org.springframework.stereotype.Component;/*** @author XWF**/
@Component
@ServerEndpoint(value = "/websocketmsgtest", encoders = {MsgATextEncoder.class}, decoders = {MsgATextDecoder.class})
public class WebSocketMsgHandler {@OnOpenpublic void onOpen() {}@OnClosepublic void onClose() {}@OnErrorpublic void onError(Throwable error) {}@OnMessagepublic void textMessageA(Session session, MsgA msga) {System.out.println("收到:" + msga);MsgA sendMsg = new MsgA();sendMsg.id = 9999;sendMsg.name = "HELLO WORLD";try {session.getBasicRemote().sendObject(sendMsg);} catch (IOException e) {e.printStackTrace();} catch (EncodeException e) {e.printStackTrace();}sendMsg.id = 8888;sendMsg.name = "hello world";Future future = session.getAsyncRemote().sendObject(sendMsg);try {future.get(3, TimeUnit.SECONDS);System.out.println("发送完毕");} catch (InterruptedException | ExecutionException | TimeoutException e) {System.out.println("超时");e.printStackTrace();}}}

测试:

不按照解码格式要求请求会异常并断开连接:

正常测试:

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
AWSECS:哪种网络模式具有... 使用AWS ECS中的awsvpc网络模式来获得最佳性能。awsvpc网络模式允许ECS任务直接在V...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...