此文是记录我上网查找整合方案时候踩的坑,特别是注册失败的问题,比如还有什么去掉@Compoent就可以,但是这样这个端点就失效了
特别是报错:
at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:159) ~[spring-websocket-6.1.1.jar:6.1.1]
at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoints(ServerEndpointExporter.java:134) ~[spring-websocket-6.1.1.jar:6.1.1]
出现这个的有几种情况
1.第一种是 onopen携带其他参数
缺少@PathParam annotation注解 如果再在端点的生命周期中,想要接收除了session,error等周期具备的基础参数,那么就需要该注解否则注册失败
Caused by: jakarta.websocket.DeploymentException: A parameter of type [class java.lang.String] was found on method[onOpen] of class [java.lang.reflect.Method] that did not have a @PathParam annotation
解决办法
周期方法的额外新参添加该注解,并且对应路由的传参"@ServerEndpoint(value = “/chat/{userName}”,configurator = GetHttpSessionConfig.class)"
@PathParam(“userName”)
2.onError周期一定要携带error
@OnError
public void onError(Throwable error) {
System.out.println("onError......"+error.getMessage());
}
3.接收对象为参数和发送对象 一定要使用解码器,否则就采用接收json字符
@OnMessage
public void onMessage(Session session,String message) throws IOException {
System.out.println("接收到消息"+message);
JSONObject json = JSON.parseObject(message);
// 从JSONObject中提取必要的字段
String sender = json.getString("sender");
String content = json.getString("content");
String toReceiver = json.getString("toReceiver");
// 创建Message对象
Message message1 = Message.builder()
.sender(sender)
// .toReceiver(toReceiver) //发给谁这个信息无需填写
.content(content)
.build();
//调用发送方的会话 发送给他的客户端显示
Session session1 = Friendgroup.get(toReceiver);
session1.getBasicRemote().sendText(JSON.toJSONString(message1));
// 你的其他逻辑
}
4.一定要注入该bean 作用是扫描注入的端点
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
如果是打包运行在tomcat容器在则不用
5.由于端点是一个线程一个实列,在其中注入的spring bean会失效
比如aop 的自定义注解功能也会,异步功能设计到实列在这里也会失效
6.同样是onOpen
@OnOpen
public void onOpen(EndpointConfig sec,Session session,@PathParam("userName") String userName){
this.userId=userName;//用户上下文填充
//2.把成功建立升级的会话让放入会话组
String sessionKey=userName;
Friendgroup.put(userName,session);
//之所以获取http session 是为了获取获取httpsession中的数据 (用户名 /账号/信息)
System.out.println("websocket建立成功");
// 2.广播消息(如果是好咧别表上下) 模拟放房间提示
String content="用户id"+sessionKey+"已经上线 愉快玩耍吧";
Message message = Message.builder()
.content(content)
.isSystem(true).build();
broadcast(message);
System.out.println("WebSocket 连接建立成功: " + sessionKey);
// 3.
}
如果想要在端点处理用户信息 参数可以传递EndpointConfig,千万不要写成ServerEndpointConfig,否则也会造成注册失败