简单实现-微服务项目Gateway转发websocket实现讨论组即时通讯

简单实现-微服务项目Gateway转发websocket实现讨论组即时通讯一 websocket 实现讨论组即时聊天的功能 1 引入依赖 dependency groupid org springframew boot groupid artifactid spring boot starter websocket artifactid lt dependency

大家好,我是讯享网,很高兴认识大家。

一、websocket实现讨论组即时聊天的功能

1、引入依赖

 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>2.0.4.RELEASE</version> </dependency>

讯享网

2、写websocket配置类

讯享网 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; / * WebSocket 配置类 * @Author Niki_Ya * @Date 2022/3/28 14:24 */ @Configuration public class WebSocketConfig { / * 用于扫描和注册所有携带ServerEndPoint注解的实例 若部署到外部容器 则无需提供此类。 * * @return org.springframework.web.socket.server.standard.ServerEndpointExporter */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } / * 在websocketServer服务注入讨论组服务接口,即时通讯的逻辑层 * * @param dmtDiscussionService dmt讨论服务 */ @Autowired public void setMessageService(DmtDiscussionService dmtDiscussionService){ WebSocketServer.dmtDiscussionService = dmtDiscussionService; } } 

3、websocket服务类实现

 import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.util.*; import java.util.concurrent.ConcurrentHashMap; / * @Description * @Author Niki_Ya * @Date 2022/3/29 10:55 */ @Slf4j @ServerEndpoint(value = "/dmt/discussion/websocket") @Component @SuppressWarnings("all") public class WebSocketServer { / * 全部在线会话 PS: 基于场景考虑 这里使用线程安全的Map存储会话对象。 */ private static final Map<String, List<Client>> ONLINE_SESSIONS = new ConcurrentHashMap<>(); //聊天逻辑层service public static DmtDiscussionService dmtDiscussionService; // 讨论组id private String discussionId; private Client client; / * 连接建立成功调用的方法,初始化 * 当客户端打开连接:1.添加会话对象 */ @OnOpen public void onOpen(Session session) { //初始化数据 String[] split = session.getQueryString().split("&"); HashMap<String, String> map = new HashMap<>(); for (String s : split) { String[] strings = s.split("="); map.put(strings[0], strings[1]); } this.discussionId = map.get("discussionId"); log.info("用户 {} 打开了{} 讨论组的WebSocket连接", map.get("staffNo"), discussionId); this.client = Client.builder() .staffId(map.get("staffId")) .staffNo(map.get("staffNo")) .staffName(map.get("staffName")) .session(session) .image(Optional.ofNullable(map.get("image")).orElse("")) .build(); if (ONLINE_SESSIONS.containsKey(discussionId)) { List<Client> clients = ONLINE_SESSIONS.get(discussionId); clients.add(client); ONLINE_SESSIONS.put(discussionId, clients); } else { List<Client> clients = new ArrayList<>(); clients.add(client); ONLINE_SESSIONS.put(discussionId, clients); } } / * 连接关闭调用的方法 */ @OnClose public void onClose() { log.info("用户 {} 关闭了 {} 的WebSocket连接", client.getStaffNo(), discussionId); // 更新最后阅读时间 DmtDiscussionDTO.UpdateLastReadTimeDTO dto = new DmtDiscussionDTO.UpdateLastReadTimeDTO(); dto.setDiscussionId(discussionId); dto.setTime(new Date()); dto.setStaffNo(client.getStaffNo()); dmtDiscussionService.updateLastReadTime(dto); //将当前的session删除 List<Client> clients = ONLINE_SESSIONS.get(discussionId); clients.remove(client); } / * 收到客户端消息后调用的方法 * * @param message 客户端发送过来的消息 */ @OnMessage public void onMessage(String message) { Long createTime = System.currentTimeMillis(); //联调:从客户端传过来的数据是json数据,所以这里使用jackson进行转换为chatMsg对象 todo DmtDiscussionDTO.Message mes = JSON.parseObject(message, DmtDiscussionDTO.Message.class); //对chatMsg进行装箱 DmtDiscussionDTO.MessageBaseDTO chatMsg = DmtDiscussionDTO.MessageBaseDTO.builder() .sendFromStaffId(client.getStaffId()) .sendFromStaffNo(client.getStaffNo()) .sendFromStaffName(client.getStaffName()) .sendFromTime(createTime) .discussionId(discussionId) .content(mes.getContent()) .type(mes.getType()) .fileType(mes.getFileType()) .image(client.getImage()) .build(); //保存聊天记录信息 DmtDiscussionMessage po = dmtDiscussionService.saveMessage(chatMsg); //声明一个map,封装直接发送信息数据返回前端 Map<String, Object> resultMap = new HashMap<>(); resultMap.put("id", po.getId()); resultMap.put("staffNo", po.getSendFromStaffNo()); resultMap.put("staffName", po.getSendFromStaffName()); resultMap.put("content", po.getContent()); resultMap.put("sendTime", po.getSendFromTime()); resultMap.put("type", po.getType()); resultMap.put("fileType", po.getFileType()); resultMap.put("image", Optional.ofNullable(po.getImage()).orElse("")); JSONObject json = new JSONObject(resultMap); //发送给接收者 List<Client> clients = ONLINE_SESSIONS.get(discussionId); clients.forEach(e -> { //异步发送消息. e.getSession().getAsyncRemote().sendText(json.toString()); }); // 发送有信息给其他在线人员 ONLINE_SESSIONS.entrySet().stream().filter(key -> !key.getKey().equals(discussionId)).forEach(e -> { e.getValue().forEach(f -> { //异步发送消息. f.getSession().getAsyncRemote().sendText(discussionId); }); }); } / * 发生错误时调用 */ @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); log.error("用户 {} 在{} 讨论组的通信发生异常 {}", client.getStaffNo(),discussionId, error.getMessage()); throw new BaseException(error.getMessage()); } } 

4、测试(测试网址:websocket在线测试)

测试地址示例:ws://本地IP地址:端口号/dmt/discussion/websocket?discussionId=&staffId=1&staffNo=ceshi001&staffName=ceshi001


讯享网

 

 二、通过网关转发webSocket

1、引入依赖(不确定需不需要)

讯享网 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </exclusion> </exclusions> </dependency>

2、配置网关路由

spring.cloud.gateway.routes[0].id = notice-websocket spring.cloud.gateway.routes[0].uri = lb:ws://notice-service spring.cloud.gateway.routes[0].predicates[0] = Path=/notice/websocket/dmt/ spring.cloud.gateway.routes[0].filters[0] = StripPrefix=2

3、测试 (测试网址:websocket在线测试)

由于我的网关一定需要传token和timestamp才可以进入,大家可以按实际要求改地址

测试地址示例:ws://本地IP地址:端口号/notice/websocket/dmt/discussion/websocket?discussionId=&staffId=&staffNo=cshi019&staffName=cshi019&token=token内容&timeStamp=时间戳毫秒

 

小讯
上一篇 2025-03-13 07:35
下一篇 2025-02-15 21:25

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/57072.html