SpringBoot整合Websocket,实现作为客户端接收消息的同时作为服务端向下游客户发送消息
SpringBoot整合Websocket
1. SpringBoot作为服务端
作为服务端时,需要先导入websocket的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
创建WebSocketServer工具类
package com.newlinker.jiangyin.utils;
/**
* @author cyl
* @time 2023/7/21
*/
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint(value = "/websocket")
public class WebSocketServer {
// 客户端会话列表
private static final Map<String, Session> clientSessions = new ConcurrentHashMap<>();
@OnOpen
public void onServerOpen(Session session) {
// 客户端连接到本地 WebSocket 服务
System.out.println("Client connected: " + session.getId());
clientSessions.put(session.getId(), session);
}
@OnMessage
public void onMessage(Session session, String message) {
// 处理客户端发送的消息
System.out.println("Received message from client " + session.getId() + ": " + message);
// 示例:将收到的消息广播给所有客户端
//broadcast(message);
}
@OnClose
public void onServerClose(Session session, CloseReason reason) {
// 客户端断开连接
System.out.println("Client " + session.getId() + " disconnected: " + reason);
clientSessions.remove(session.getId());
}
@OnError
public void onError(Session session, Throwable throwable) {
// 客户端连接发生错误
System.out.println("WebSocket client error: " + throwable.getMessage());
clientSessions.remove(session.getId());
}
// 发送消息给指定客户端
public void sendToClient(String clientId, String message) {
Session session = clientSessions.get(clientId);
if (session != null && session.isOpen()) {
session.getAsyncRemote().sendText(message);
}
}
// 广播消息给所有客户端
public void broadcast(String message) {
for (Session session : clientSessions.values()) {
if (session.isOpen()) {
session.getAsyncRemote().sendText(message);
}
}
}
// 关闭客户端连接
public void closeClientConnection(String clientId) {
Session session = clientSessions.get(clientId);
if (session != null && session.isOpen()) {
try {
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Closing connection"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
添加Spring Bean配置
package com.newlinker.jiangyin.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* @author cyl
* @time 2022/4/11
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
至此,SpringBoot已可作为服务端进行websocket连接测试,测试时的路径为:
ws://localhost:port/websocket
其中若SpringBoot配置了ssl证书可提供https访问,则应将websocket连接协议更改为wss
websocket路径中的"/websocket"由@ServerEndpoint注解决定,推荐使用在线测试,简单方便
2. SpringBoot作为客户端
作为客户端,推荐使用okhttp的依赖以及google的gson转换包(可与上方的依赖共存,不用担心)
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
<!-- 非必须,可以使用其他JSON包进行处理 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
创建WebSocketClient工具类
package com.newlinker.jiangyin.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.newlinker.jiangyin.config.XingHuoConfig;
import com.newlinker.jiangyin.entity.ro.Payload;
import com.newlinker.jiangyin.entity.ro.ResponseData;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.websocket.OnError;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author cyl
* @time 2022/4/11
*/
@Component
public class WebSocketClient extends WebSocketListener {
//注入你的WebSocketServer工具类
@Autowired
private WebSocketServer webSocketServer;
private WebSocket webSocket;
// 客户端连接其他服务器
public void connectToServer(String serverUrl) {
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url(serverUrl).build();
webSocket = okHttpClient.newWebSocket(request, this);
}
@Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
}
//收到消息时触发,核心逻辑
@Override
public void onMessage(WebSocket webSocket, String text) {
ResponseData responseData = GSON.fromJson(text, ResponseData.class);
//此处服务器返回的status值为0时代表连接正常,由接口具体情况而定,与协议无关
if (0 == responseData.getHeader().get("code").getAsInt()) {
Payload pl =GSON.fromJson(responseData.getPayload(), Payload.class);
JsonArray temp = (JsonArray) pl.getChoices().get("text");
JsonObject jo = (JsonObject) temp.get(0);
//解析结果后将内容转发给下游客户端,也可以使用sendMessage方法定向发送
webSocketServer.broadcast(jo.get("content").getAsString());
//如果不想每次发送消息时都主动连接,需要建立websocket心跳,这里每次收发消息都主动断开
webSocket.close(3, "客户端主动断开链接");
}
} else {
System.out.println("返回结果错误:\n" + responseData.getHeader().get("code") + " " + responseData.getHeader().get("message"));
}
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
System.out.println("WebSocket连接失败:");
super.onFailure(webSocket, t, response);
System.out.println(response);
}
@OnError
public void onError(Session session, Throwable throwable) {
System.out.println("WebSocket发生错误:" + throwable.getMessage());
}
//可以在Controller中调用该方法进行websocket的手动发送以及参数调整
public void sendMessage(String word) {
connectToServer();
JsonObject frame = new JsonObject();
//根据自己的需求填充你的请求参数
//...
webSocket.send(frame.toString());
System.out.println(frame.toString());
}
}
SpringBoot整合Websocket,实现作为客户端接收消息的同时作为服务端向下游客户发送消息的更多相关文章
- springboot整合websocket实现一对一消息推送和广播消息推送
maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Springboot整合Websocket遇到的坑
Springboot整合Websocket遇到的坑 一.使用Springboot内嵌的tomcat启动websocket 1.添加ServerEndpointExporter配置bean @Confi ...
- SpringBoot 整合 WebSocket
SpringBoot 整合 WebSocket(topic广播) 1.什么是WebSocket WebSocket为游览器和服务器提供了双工异步通信的功能,即游览器可以向服务器发送消息,服务器也可以向 ...
- springboot整合websocket原生版
目录 HTTP缺点 HTTP websocket区别 websocket原理 使用场景 springboot整合websocket 环境准备 客户端连接 加入战队 微信公众号 主题 HTTP请求用于我 ...
- springboot整合websocket高级版
目录 sockjs介绍 产生的原因 环境搭建 springboot整合sockjs 使用场景 聊天室开发 点对点通信 群聊 效果 总结 加入战队 微信公众号 上一章节我们说了websocket的优缺点 ...
- SpringBoot整合websocket简单示例
依赖 <!-- springboot整合websocket --> <dependency> <groupId>org.springframework.boot&l ...
- spring集成webSocket实现服务端向前端推送消息
原文:https://blog.csdn.net/ya_nuo/article/details/79612158 spring集成webSocket实现服务端向前端推送消息 1.前端连接webso ...
- Android消息推送的服务端
2.Android消息推送 MQTT服务器采用mosquito http://mosquitto.org/ PHP管理包采用phpmqttclient:https://github.com/toku ...
- WebService或HTTP服务端接收请求转发消息到另一个服务端-实现思路
1.需求结构(WebService) A客户端<->B服务端<->C服务端 说明: a.在B服务端上面添加配置项(1.是否转发消息到C服务端:2.C服务端IP和端口): b.A ...
- 客户端 new socket时候 就像服务端发起连接了
客户端 new socket时候 就像服务端发起连接了
随机推荐
- Nginx配置https并监听80端口重定向到443
1.进入nginx安装目录,进入config文件夹编辑nginx.conf文件 vim nginx.conf 配置端口 443 listen 443 http2 ssl default_server ...
- asyncio的基本使用框架,python高效处理数据,asyncio.gather(),asyncio. create_task(),asyncio.run(main())
asyncio 是 Python 3.4 引入的标准库,是一个基于事件循环的异步 I/O 并发库.它提供了一种协作式的多任务处理方式,使得我们能够在一个线程中并发处理多个 I/O 操作.它通过将 I/ ...
- css 文本超出,显示省略号
单行文本省略号 显示省略号 text-overflow: ellipsis; overflow: hidden; max-width: 110px; 文本不换行 wor ...
- taro-ui Calendar 修改星期开始时间为星期一(中国格式)
官网Calendar文档:http://taro-ui.jd.com/#/docs/calendar 日历虽然兼容性很高,小程序也能使用,但扩展性并不高,如果需要更强的样式/自定义,需要复制部分源码到 ...
- YOLO1论文中文版
文章目录 YOLO1中文版 摘要 1. 引言 2. 统一检测 2.1 网络设计 2.2 训练 2.3 推断 2.4 YOLO的限制 3. 与其它检测系统的比较 4. 实验 4. 1 与其它实时系统的比 ...
- 2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个从 1 到 n 且互不相同的值 另给你一个长度为 m 的数组 queries 你必须在树上执行
2023-05-03:给你一棵 二叉树 的根节点 root ,树中有 n 个节点 每个节点都可以被分配一个从 1 到 n 且互不相同的值 另给你一个长度为 m 的数组 queries 你必须在树上执行 ...
- ATL创建的ActiveX实现JS回调
最近公司的产品需要使用ActiveX文件上传.讨论了基本所有的技术,最后还是决定C++搞个ActiveX...但上传的回调费了半天劲,才搞定.代码如下 STDMETHODIMP CFileSelect ...
- STL------sort三种比较算子定义
sort的三种比较算子的定义方式 例:一道细碎的细节模拟题: http://newoj.acmclub.cn/contests/1258/problem/3 1932: 2018蓝桥杯培训-STL应用 ...
- 2022-07-06:以下go语言代码是否会panic?A:会;B:不会。 package main import “C“ func main() { var ch chan struct
2022-07-06:以下go语言代码是否会panic?A:会:B:不会. package main import "C" func main() { var ch chan st ...
- 2022-04-29:厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子。 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子。 如果剩余橘子数 n 能被
2022-04-29:厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子. 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子. 如果剩余橘子数 n 能被 ...