【websocket】使用websocket实现springboot与浏览器的通信
网上翻了很多介绍的使用方法都是没有请求头条件下使用的,但是为了安全问题一般都会加上请求头进行验证,这是携带token进行连接的方法
网上翻了很多介绍的使用方法都是没有请求头条件下使用的,但是为了安全问题一般都会加上请求头token进行验证,原生websocket是不支持自定义携带请求头的,如果一定要加应该是只能加到Sec-WebSocket-Protocol的位置,如果有更好的方法欢迎指点,
实现代码如下:
前端部分
这一块比较简单,只要在原有的构造方法加上第二个参数,也就是token即可,加上以后在ws请求的请求头’Sec-WebSocket-Protocol‘就会携带着token,后端可以获取并进行相应的解析处理
let socket = new WebSocket('ws://localhost:8080/ws/1', ['验证token']);
// 连接成功后触发
socket.onopen = () => {
console.log('WebSocket 已连接');
// 向服务端发送消息
socket.send('Hello Server!');
};
// 接收到服务端发送的消息时触发
socket.onmessage = (event) => {
console.log(`接收到消息:${event.data}`);
};
// 连接关闭时触发
socket.onclose = (event) => {
console.log('WebSocket 已关闭', event);
};
// 发生错误时触发
socket.onerror = (error) => {
console.error('WebSocket 发生错误:', error);
};
后端部分
添加依赖websocket依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>${spring-boot.version}</version>
</dependency>
在使用Spring Boot开发WebSocket应用程序时,需要将WebSocket端点暴露为Spring Bean,以便于Spring容器管理WebSocket端点的生命周期。通常情况下,需要创建一个ServerEndpointExporter实例并将其声明为Spring Bean。
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
当WebSocket请求获取请求头Sec-WebSocket-Protocol不为空时,需要返回给前端相同的响应,所以就需要处理:
在 WebSocketConfig 中新增 modifyHandshake方法,用来获取请求头和为返回响应赋值
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
@Slf4j
@Component
public class WebsocketConfig extends ServerEndpointConfig.Configurator{
/**
* 重写modifyHandshake方法,获取Sec-WebSocket-Protocol请求头
* @param sec
* @param request
* @param response
*/
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
//当Sec-WebSocket-Protocol请求头不为空时,需要返回给前端相同的响应
response.getHeaders().put("Sec-WebSocket-Protocol", request.getHeaders().get("Sec-WebSocket-Protocol"));
super.modifyHandshake(sec, request, response);
}
}
注意要在**@ServerEndpoint** 注解中加上 configurator = WebSocketConfig.class,也就是将该配置绑定到endpoint上面
import com.alibaba.fastjson.JSON;
import com.wss.gis.view.vo.ServerMessage;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author WuShuaiShuai
* @since 2023/3/3-16:12
*/
@Slf4j
@Component
@ServerEndpoint(value = "/ws/{param}",configurator = WebsocketConfig.class)
public class CollectEndpoint {
//用来存储每个连接的客户端chatEndpoint
private static final ConcurrentHashMap<Long, CollectEndpoint> onLineUsers = new ConcurrentHashMap<>();
Session session;
/**
* 连接建立时调用
* @param param 用户id
* @param session 会话
*/
@OnOpen
public void onOpen(@PathParam("param")Long param, Session session) {
this.session = session;
log.info("{}", onLineUsers.get(param));
//将当前对象存储到容器中,先查看是否已经链接
onLineUsers.put(param, this);
//将当前在线的用户名推送给所用用户端
log.info("你有新的链接:{}", param);
onLineUsers.get(param).session.getAsyncRemote().sendText("你好");
}
/**
* 接受客户端的消息时调用
* @param message 消息
* @param session 会话
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到消息:" + message);
}
/**
* 关闭客户端时调用
*/
@OnClose
public void onClose(@PathParam("param")Long param) {
log.info("关闭链接:{}", param);
onLineUsers.remove(param);
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误:{}", error.getMessage());
error.printStackTrace();
}
// public Boolean sendMessage(@NotNull ServerMessage serverMessage, Long toUserId) {
// log.info("在线人数:{}", onLineUsers.size());
// CollectEndpoint chatEndpoint = onLineUsers.get(toUserId);
// boolean flag = false;
// try {
// if (chatEndpoint != null) {
// serverMessage.setFrom(name.toString());
// serverMessage.setTo(toUserId.toString());
// chatEndpoint.session.getBasicRemote().sendText(JSON.toJSONString(serverMessage));
// flag = true;
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// return flag;
// }
}

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)