引言
学完了协议基础,我们一起使用spring-boot
搭建一个websocket
项目。
WebSocket 实现
以下的代码实现十分简单,建立起WebSocket
连接后,后台向前台推送一些数据,前台回复收到。
后台
如下所示,后台编写一个Handler
,实现WebSocketHandler
拥有处理WebSocket
的能力,实现方法。
@Component
public class YunzhiWebSocketHandler implements WebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
System.out.println("建立连接");
webSocketSession.sendMessage(new TextMessage("Hello!"));
webSocketSession.sendMessage(new TextMessage("This is yunzhiclub."));
webSocketSession.sendMessage(new TextMessage("I am yunzhi's server."));
webSocketSession.sendMessage(new TextMessage("I am sending message."));
}
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
System.out.println("收到数据" + webSocketMessage.getPayload().toString());
}
@Override
public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
System.out.println("发生错误");
}
@Override
public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
System.out.println("连接关闭");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}
前台
前台不引入任何JavaScript
第三方库,直接使用原生WebSocket API
实现。
建立WebSocket
连接。
var websocket = new WebSocket('ws://127.0.0.1:8080/websocket');
websocket.onpen = function(event) {
console.log('建立WebSocket连接');
};
websocket.onclose = function(event) {
console.log('关闭WebSocket连接');
};
websocket.onmessage = function(event) {
console.log('收到消息', event.data);
websocket.send('收到!');
};
websocket.onerror = function() {
console.log('WebSocket发生错误');
};
window.onbeforeunload = function() {
websocket.close();
};
路由配置
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
private final YunzhiWebSocketHandler handler;
public WebSocketConfig(YunzhiWebSocketHandler handler) {
this.handler = handler;
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(handler, "websocket").setAllowedOrigins("*");
}
}
效果
在网络中,即可查看WebSocket
的数据收发情况。
不足分析
写完WebSocket
代码之后,突然觉得自己之前举的在线聊天的栗子不好实现。单一用户的推送,使用WebSocket
很困难。
推送的时候,需要使用WebSocketSession
进行推送,所以就需要验证WebSocketSession
与用户之间的对应关系。
用户认证可以使用token
来实现。
认证
之前我们讲过,WebSocket
的建立需要先发送HTTP
请求进行握手,我们可以在握手中鉴别用户身份。
握手拦截器,此处是获取token
的示例,就像普通的HTTP
一样。
@Component
public class WebSocketInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
if (serverHttpRequest instanceof ServletServerHttpRequest) {
ServletServerHttpRequest request = (ServletServerHttpRequest) serverHttpRequest;
String token = request.getServletRequest().getParameter("token");
System.out.println(token);
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
}
}
配置拦截器:
private final WebSocketInterceptor interceptor;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(handler, "websocket").addInterceptors(interceptor).setAllowedOrigins("*");
}
前台在建立连接的时候添加token
认证信息:
var websocket = new WebSocket('ws://127.0.0.1:8080/websocket?token=23147823975891374859435');
在握手的时候,后台即可获取token
信息,获悉用户身份。
总结
最近的感觉就是语言和框架的重要性逐渐降低,我不再喜欢去看什么《Spring Boot
核心思想》、《Spring Cloud
微服务实战》这些书,学完真的感觉没什么用,没人敢保证一项技术长青。
现在,我开始学习IO
模型、学习Linux
。
字节跳动的消(cu
)极(si
)事件(小声,据说查得挺严的),让我庆幸挂在三面。同时,我也似乎感悟更深。
别拘泥框架,技术不止框架。别迷恋技术,人生远比这广。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。