网上有很多写WebSocket搭建的案例,我这里也是主要记录一下,我在部署WebSocket上踩到的坑。案例主要是给自己记录一下 我这里是用SpringBoot 搭建的WebSocket 首先就是配置类的代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
在之后就是WebSocket的核心代码,消息的接收和连接的建立都是基于这个类
@Service
@ServerEndpoint("/webSocket/{userId}")
public class WebSocketServerImp{
private static ApplicationContext applicationContext;
private static ConcurrentHashMap<Long,Session> webSocketMap = new ConcurrentHashMap<>();
public static void setApplicationContext(ApplicationContext applicationContext) {
WebSocketServerImp.applicationContext = applicationContext;
}
@OnOpen
public void onOpen(Session session, @PathParam("userId") Long userId) {
webSocketMapper = applicationContext.getBean(WebSocketMapper.class);
this.userId = userId;
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
webSocketMap.put(userId,session);
}else{
webSocketMap.put(userId,session);
}
}
@OnClose
public void onClose() {
}
@OnMessage
public void onMessage(String jsonMessage) {
}
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
error.printStackTrace();
}
}
因为我们在@ServerEndpoint这个类里面加了private static ApplicationContext applicationContext;,也有set方法那我们也应该在哪里set呢?答案是启动类,从启动类获取上下文,然后set 启动类代码:
@SpringBootApplication
@MapperScan("com.xxx.server.mapper")
public class YebApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(YebApplication.class, args);
WebSocketServerImp.setApplicationContext(applicationContext);
}
}
webSocket 的代码到这里就结束了。下面来说一下有那些坑 1、需不需要加@Service或@Component?网络上有些人说@ServerEndpoint本身就有@Component我尝试不要这种bean注册注解,我的@ServerEndpoint是没有自带bean注册注解的,可能是版本问题吧,我觉得是需要加的加了规范一点,至少让别人看你类的时候也会舒服一点 2、@OnError 这个类里面的形参必须要有Throwable error这个形参,不然你的@ServerEndpoint会注册失败 3、@OnClose 这个类里面的形参不能有任何参数,不然就是注册失败,这个坑我踩了很久! 4、在@ServerEndpoint中@Autowired这类自动注入注解失败问题,这个问题我在上面的代码注释里面也说了,主要原因就是spring和websocket犯冲,一个是单例,一个是多例
|