SpringBoot集成WebSocket遇到的问题最近在项⽬中需要使⽤WebSocket,因为项⽬是使⽤的SpringBoot架构,所以集成⽐较简单。
上代码:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocketServer.java
slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import urrent.CopyOnWriteArraySet;
/**
* web socket ⼯具类
*
* @author alvinqiu
* @data 2018/10/24
*/
@Slf4j
@Component
@ServerEndpoint(value = "/ws/{type}")
public class WebSocketServer {
/**
* concurrent包的线程安全Set,⽤来存放每个客户端对应的Session对象
*/
private static CopyOnWriteArraySet<Session> SessionSet = new CopyOnWriteArraySet<Session>();
@OnOpen
public void onOpen(@PathParam("type") String type, Session session) {
SessionSet.add(session);
log.info("WebSocket有连接加⼊, 请求的数据类型为: " + type);
try {
sendMessage("Hello WebSocket " + type);
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void onClose(Session session) {
log.info("WebSocket有连接关闭");
}
@OnError
public void onError(Throwable error) {
log.info("WebSocket发⽣错误, 原因: " + Message());
}
@OnMessage
public void onMessage(String message) {
log.info("收到来⾃WebSocket客户端的消息: " + message);
}
/**
* 发送消息给客户端
*
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException {
for (Session session : SessionSet) {
if (session.isOpen()) {
}
}
}
}
WebSocketConfig.java
import t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* web socket 配置类
*
* @author alvinqiu
* @data 2018/10/24
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
客户端就不写了,上⾯的代码也没什么好说的,相当简单,项⽬跑起来就完事⼉咯
结果就这简单玩意⼉出现了问题
项⽬运⾏
java.lang.IllegalStateException: Failed to register @ServerEndpoint class: WebSocketServer$$EnhancerBySpringCGLIB$$62689f33
javax.websocket.DeploymentException: Cannot deploy POJO class [WebSocketServer$$EnhancerBySpringCGLIB$$62689f33] as it is not annotated with 报错了?怎么会呢,这么简单的⼀个玩意⼉,⽹上的教程不都是这么⼲的吗
研究下错误,标注了@ServerEndPoint注解的类注册失败,百思不得其解,百度⾕歌⼀番,什么jdk版本、tomcat版本、需不需要注⼊ServerEndpointExporter等等等等,我项⽬情况都不是(jdk1.8、tomcat8+、springboot内置容器)
后来想想是否因为项⽬是多模块结构的原因,可能是jar包冲突、循环依赖,什么可能都想过,然后新建了⼀个springboot项⽬,只集成websocket试试,结果是正常运⾏的,版本⼀致,环境⼀致,代码⼀致,问题看来出在项⽬本⾝了
项⽬结构:
⽗⼯程springboot结构
A 模块(启动模块,依赖了其他所有⼦模块,⼀些公共的配置类)
B 模块(业务模块)
...
...
Q 模块(WebSocket模块)
难道是WebSocket作为⼀个单独模块出的飞机? 这么扯的理由我也不管了,还是把它挪到了A 模块去,结果问题依旧....
前后折腾了很久,终于决定跟跟源码
恩,就是这⾥annotation为null,⾄于为何为null还是不知道,突发奇想去看看另⼀个springboot项⽬(成功案例),
恩,annotation是有值的
发现了pojo的区别:
(报错)
websocket.WebSocketServer$$EnhancerBySpringCGLIB$$62689f33
(成功)
websocket.WebSocketServer
后⾯那⼀串是代表类被cglib转换为了代理对象,什么情况下会被转换为代理对象?
AOP!AOP!AOP!
简直是如梦初醒,虎躯⼀震
我的 A 模块⾥是写了⼀个全局的log⽇志切⾯
⼤概是这样:
/**
* ⽇志切⾯
*
* @author alvinqiu
* @date 2018/09/28
*/
@Slf4j
@Aspect
@Component
public class AspectLog {
@Pointcut("execution(* *.*(..))")
public void aspectLog() {
}
@Pointcut("execution(* api..*.*(..))")
public void aspectApiLog() {
}
@Pointcut("execution(* service..*.*(..))")
public void aspectServiceLog() {
}
@Pointcut("execution(* apper..*.*(..))")
public void aspectMapperLog() {
}
...
...
}
问题出来咯,WebSocketServer这个类被切咯,以⾄于@ServerEndPoint注解⽆法注⼊⾄对应的对象,导致报错
解决
AOP 排除此类
总结
1. 出问题多跟跟源码
2. 多与⼤神交流,碰撞,⽆论多么难以描述的问题,全世界都对,你的项⽬不对,也要与⼤神沟通,⼀点点的终究会得到思路此问题捣⿎了⼀周有余,现在看来多么基础、初级、菜鸡,但,解决过程真⼼⾎泪史,写在这⾥,多年后回来乐⼀乐
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论