[websocket]关于使⽤websocket时遇到的坑
因为websocket是第⼀次接触,所以遇到的问题很多,需要⾃⼰⼀点⼀点去踩。
在这⾥主要说明使⽤@ServerEndpoint注解⽅式时遇到的问题以及解决⽅法
1.启动包类型不同带来的问题
使⽤的是Springboot框架,所以开发时使⽤jar包⽅式运⾏,这时启动类不需要更改,只需要加⼀个配置⽂件,如下:
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
这样就可以使⽤websocket了。
但由于线上使⽤docker部署的,⽽且使⽤的是war包,所以这时就要把jar改成war,怎么改的这⾥就不赘述了,只需要改⼀下启动类就⾏。⽹上很多资料,我也是照着⽹上的步骤改的,然后⽤外置的tomcat启动,注意是外置的,问题来了,报错,如下:
Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
at org.springframework.util.Assert.state(Assert.java:70)
at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterPropertiesSet(ServerEndpointExporter.java:102)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1689) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1627) ... 63 common frames omitted
报了个websocket的服务器容器不可⽤。于是我到⽹上查了⼀下,但没到。然后我就去查是不是jar问题,发现也没冲突。想了很久,也
查了很多⽹站也没到,突然想到是不是注解的问题,就去看了这个@ServerEndpoint是哪个jar包的,发现是tomcat相关包下⾯的,这样问题就到了,之前我们jar包启动,需要配置⼀个ServerEndpointExporter,这个配置的⽬的就是把到@ServerEndpoint注解的bean,交给Spring管理,但是现在,我们使⽤tomcat启动,⾃然不需要在配置了,直接交由tomcat容器管理。然后把这个配置注释掉,
在启动tomcat,可以正常启动。
2.websocket handle类注⼊问题
使⽤websocket时,⼀般是写⼀个handle类⽤来接收或发送消息,也就是配置@OnOpen、@OnMessage、@OnError等注解的。
因为要处理业务,所以要注⼊⼀些服务,但是⽤@Autowrited、@Resource、@Component等等都不起作⽤。所以在这⾥提供⼀种新的
⽅法,⼿动注⼊
将这个handle类实现ApplicationContextAware接⼝,然后重写setApplicationContext⽅法。如下:
@ServerEndpoint("/ws")
@Component
public class MyWebsocketHandle implements ApplicationContextAware {
/**
* 定义applicationContext
*/
private static ApplicationContext applicationContext;
/**
* 要注⼊的业务接⼝
*/
private WebsocketAdapter websocketAdapter;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
MyWebsocketHandle.applicationContext = applicationContext;
}前端websocket怎么用
private void init(){
if (websocketAdapter == null){
synchronized (MyWebsocketHandle.class){
if (websocketAdapter == null){
websocketAdapter = Bean(WebsocketAdapter.class);
}
}
}
}
}
⾃定义ApplicationContext也可在启动类中创建,启动时直接指定定义的类。如果使⽤tomcat部署的话在启动类中可能会有问题。上⾯⽤到了双检锁,也可以根据⾃⾝业务情况使⽤其他单例的设计模式。
以上是使⽤tomcat包中注解的⽅式,⽤Spring集成的websocket也可以,有时间会写⼀下⽤那种⽅法时遇到的坑。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。