一、重点导读
1、拦截器的配置:由于WebSocket不能像http那样很简单的将token设置到请求头中,而基于token的拦截器基本都是在请求头中获取token,因此不能拦截WebSocket的请求,否则会报错空指针异常。token除了放在请求头,还能放在请求地址,因此可以采取路径变量或者使用?拼接在地址栏。用户信息的获取放在ChatEndpoint 中并根据token获取
2、ChatEndpoint 中如何获取token,使用路径变量+WebSocket的@PathParam注解
3、ChatEndpoint 中如何根据token获取当前的用户id
4、为了安全,用户id不要拼接在地址栏,如果后端使用前端传来的id,这很不安全,因为可能用户登录的账号id与地址栏中的id不同,这样用户就使用了别人的账号发送消息
二、代码
1、导入依赖
<!-- websocket-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--token-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
</dependency>
2、在SpringBoot容器中注册WebSocket
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
/**
* 扫描注解了@ServerEndpoint注解的类
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、端点类(核心逻辑)
关键代码:
@ServerEndpoint(value = "/chat/{token}")
User tokenUser = TokenUtils.getUser(token);
对应的请求:ws://localhost:9090/chat/{token}
如:ws://localhost:9090/chat/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxMzAiLCJleHAiOjE2NjE0MDYzMjl9.XEktvzwASqWvBRkbFPPZ3cCntOxB4bPjOR4hjGpCuas
因为使用的token,因此数据没有选择去session中取,如果有需要session做法的小伙伴可以去参考b站WebSocket打造在线聊天室【完结】_哔哩哔哩_bilibili