最近在看 Spring Boot里面的WebSocket 刚好以前用过socket写过小游戏,就动手打了Demo,期间遇到不少问题,在这里分享下。
首先,使用websocket的话,在spring里面可以直接使用,但是目前来说,不是所有浏览器和服务器都支持websocket,考虑实际需求的话,还是要加上sock.js,这样才能保证实现的产品稳定性。
直接实现的话,这篇文章 写的不错,代码我跑过可以运行,这里按下不表。
使用socket.js的话,有会几个坑。先上书上代码:
第一步当然是建立Spring Boot Project
第二步,在pom文件加入WebSocket的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
第三步,编写Handler类
@Component
public class MarcoHandler extends AbstractWebSocketHandler {
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
Thread.sleep(2000);
System.out.println(message.toString());
session.sendMessage(new TextMessage("Polo!"));
}
}
这个类拓展了
AbstractWebSocketHandler 这个类,主要是实现 WebocketHandler 这个接口,从而使用Spring的底层级WebSocet API来处理消息文本。
handleTextMessage 是 AbstractWebSocketHandler 其中的一个方法,重写该方法处理文本类型的消息。
有了处理消息的方法,接下来,就是把消息导入到这里,那么剩下的工作就简单了,接受浏览器的请求,并分配到这个方法来。为此,我们需要一个配置类。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
MarcoHandler marcoHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
//webSocketHandlerRegistry.addHandler(marcoHandler,"/marco").setAllowedOrigins("*").withSockJS();
webSocketHandlerRegistry.addHandler(marcoHandler,"/marco").setAllowedOrigins("http://localhost:63342").withSockJS();
}
}
首先必须把上一把写好的处理消息类当成bean依赖进来,然后实现WebSocketConfigurer接口重写里面的注册方法注册一个端点,里面这个端点来接收来自“/marco” 的请求,然后把它分配给我们上一步创建好的bean,简单明了吧~
第三步,浏览器端
var url = "http://localhost:8090/marco";
var sock = new SockJS(url);
sock.onopen = function(){
console.log("opening");
sayMarco();
};
sock.onmessage = function(e){
console.log("Receive message: " , e.data);
setTimeout(function(){sayMarco()},2000);
};
sock.onclose = function(){
console.log("Closing");
};
function sayMarco(){
console.log("Sending marco!");
sock.send("Marco");
}
首先,因为是 sock.js 的原因,所以url 是 http或者https,而不能使 ws
其次,生成 sockjs 对象,然后重写里面的onopen,onmessage,onclose 等方法就可以了
OK,代码总算搬完了,坑在哪里呢
1、 无论我之前怎么改 url 都是报 404 NOT FOUND 错误
后来发现我的配置类没有加 @Config 注解,导致注册的端点没注册上,所以才报404
2、加上 注解之后 改成报 403 错误
后来墙了一下,发现是 跨域问题,因为Spring为了保护应用,帮我们加了拦截器防止跨域,所以我们可以在配置类使用 setAllowedOrigins("*")
这个方法允许我们跨域访问,但是 spring官方 推荐的方式是这样的
.setAllowedOrigins("http://mydomain.com")
这个看具体应用了吧