日常工作中,我们都是使用http请求,来进行前后交互,那么我们也会有使用websocket来进行前后交互的时候,那么它俩有什么区别呢?
http和websocket区别
- WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息
- HTTP是单向的
- WebSocket是需要浏览器和服务器握手进行建立连接的
- 而http是浏览器发起向服务器的连接,服务器预先并不知道这个连接
根据它的特点就可以知道,如果场景中需要服务端向客户端推送消息,那么使用http就是不行的。所以今天就用spring boot 来接入 WebSocket。
代码实现
首先,我们需要在pom文件内引入它的jar包依赖,如下:
org.springframework.boot spring-boot-starter-websocket
这个时候我们就可以直接利用该第三方的API直接代码实现了。
新增websocket配置类
因为项目中有http请求,也有websocket请求,那么该怎么去区分请求连接的类型呢?这个时候我们需要增加一个websocket的配置类,来进行拦截websocket的请求。
@Configurationpublic class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}
注意:不要忘记添加 @Configuration 注解,这个类,会自动拦截websocket请求。
完整代码
@Component@Slf4j@ServerEndpoint("/websocket/{userId}")public class WebSocketHandler { // 接口路径 ws://127.0.0.1:9000/websocket/userId; private Session session; //concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。 private static CopyOnWriteArraySet webSocketUtils = new CopyOnWriteArraySet<>(); // 用来存在线连接数 private static Map sessionPool = new HashMap<>(); @OnOpen public void onOpen(Session session, @PathParam(value = "userId") String userId) { try { this.session = session; webSocketUtils.add(this); sessionPool.put(userId, session); sendOneMessage(userId, "连接成功"); //加入队列 QueueUtils.addMap(userId); log.info("【websocket消息】有新的连接,总数为:" + webSocketUtils.size()); } catch (Exception e) { e.printStackTrace(); } } @OnClose public void onClose() { try { webSocketUtils.remove(this); log.info("【websocket消息】连接断开,总数为:" + webSocketUtils.size()); } catch (Exception e) { e.printStackTrace(); } } @OnMessage public void onMessage(@PathParam(value = "userId") String userId, String message) { log.info("【websocket消息】收到客户端消息:" + message); if (!StringUtils.isEmpty(userId) && !StringUtils.isEmpty(message) && message.equals("ping")) { sendOneMessage(userId, "pong"); } else { //1、轮询用户数最少的服务器IP String serverIP = QueueUtils.getServer(); log.info("serverIP为:" + serverIP); //2、调用大模型 WebSocketClient client = JavaClient.getClient(userId, serverIP); if (client != null) { JSONObject object = new JSONObject(); object.put("", message); String[][] strings = {{"aaa"}}; object.put("history", strings); object.put("knowledge_base_id", "/home/nemo/aigc/langchain-ChatGLM/vector_store/knowledge_FAISS_20230516_133609"); //3、发送问题 client.send(object.toString()); } } } @OnError public void onError(Session session, Throwable error) { log.error("用户错误,原因:" + error.getMessage()); error.printStackTrace(); } public static Runnable sendOneMessage(String userId, String message) { Session session = sessionPool.get(userId); if (session != null && session.isOpen()) { try { log.info("【推给前端消息】 :" + message); //高并发下,防止session占用期间,被其他线程调用 synchronized (session) { session.getBasicRemote().sendText(message); } } catch (Exception e) { e.printStackTrace(); } } return null; }}
测试
我们可以使用第三方websocket在线测试工具,http://www.jsons.cn/websocket/,连进行测试。
我们可以发送请求连接为:ws://127.0.0.1:9000/websocket/1
然后点击Websocket连接,即客户端可以收到服务端的回应:连接成功。
来源地址:https://blog.csdn.net/weixin_44427181/article/details/130949100