当前位置: 首页 > news >正文

websocket的使用

1.引入依赖

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

2.配置websocket服务

@Configuration
public class WebSocketConfig {/*** 配置WebSocket服务* @return*/@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

3.启动类添加注解

@EnableWebSocket

4.websocket服务端逻辑

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;/*** WebSocketServer服务端*/
@Slf4j
@Component
@ServerEndpoint("/websocket/{uid}")
public class WebSocketClient {/*** 静态变量,用来记录当前在线连接数,线程安全的类。*/private static AtomicInteger onlineSessionClientCount = new AtomicInteger(0);/*** 存放所有在线的客户端*/private static Map<String, Session> onlineSessionClientMap = new ConcurrentHashMap<>();/*** 连接uid和连接会话*/private String uid;private Session session;/*** 连接建立成功调用的方法。由前端<code>new WebSocket</code>触发** @param uid     每次页面建立连接时传入到服务端的id,比如用户id等。可以自定义。* @param session 与某个客户端的连接会话,需要通过它来给客户端发送消息*/@OnOpenpublic void onOpen(@PathParam("uid") String uid, Session session) {/*** session.getId():当前session会话会自动生成一个id,从0开始累加的。*/log.info("连接建立中 ==> session_id = {}, sid = {}", session.getId(), uid);//加入 Map中。将页面的uid和session绑定或者session.getId()与session//onlineSessionIdClientMap.put(session.getId(), session);onlineSessionClientMap.put(uid, session);//在线数加1onlineSessionClientCount.incrementAndGet();this.uid = uid;this.session = session;sendToOne(uid, "连接成功");log.info("连接建立成功,当前在线数为:{} ==> 开始监听新连接:session_id = {}, sid = {},。", onlineSessionClientCount, session.getId(), uid);}/*** 连接关闭调用的方法。由前端<code>socket.close()</code>触发** @param uid* @param session*/@OnClosepublic void onClose(@PathParam("uid") String uid, Session session) {//onlineSessionIdClientMap.remove(session.getId());// 从 Map中移除onlineSessionClientMap.remove(uid);//在线数减1onlineSessionClientCount.decrementAndGet();log.info("连接关闭成功,当前在线数为:{} ==> 关闭该连接信息:session_id = {}, sid = {},。", onlineSessionClientCount, session.getId(), uid);}/*** 收到客户端消息后调用的方法。由前端<code>socket.send</code>触发* * 当服务端执行toSession.getAsyncRemote().sendText(xxx)后,前端的socket.onmessage得到监听。** @param message* @param session*/@OnMessagepublic void onMessage(String message, Session session) {/*** html界面传递来得数据格式,可以自定义.* {"sid":"user-1","message":"hello websocket"}*/log.info("接收到消息-----------------"+message);List<String> uids = session.getRequestParameterMap().get("uid");for (String uid : uids) {// 接收前端拖推送改的消息sendToOne(uid, "来自服务端的推送=====》你好前端! 我已经成功收到消息!消息数据为:" + message);}}/*** 发生错误调用的方法** @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("WebSocket发生错误,错误信息为:" + error.getMessage());error.printStackTrace();}/*** 群发消息** @param message 消息*/public void sendToAll(String message) {// 遍历在线map集合onlineSessionClientMap.forEach((onlineSid, toSession) -> {// 排除掉自己if (!uid.equalsIgnoreCase(onlineSid)) {log.info("服务端给客户端群发消息 ==> sid = {}, toSid = {}, message = {}", uid, onlineSid, message);toSession.getAsyncRemote().sendText(message);}});}/*** 指定发送消息** @param toUid* @param message*/public boolean sendToOne(String toUid, String message) {/** 判断发送者是否在线*/Session toSession = onlineSessionClientMap.get(toUid);if (toSession == null) {log.error("服务端给客户端发送消息 ==> toSid = {} 不存在, message = {}", toUid, message);return false;}// 异步发送log.info("服务端给客户端发送消息 ==> toSid = {}, message = {}", toUid, message);toSession.getAsyncRemote().sendText(message);return true;}}

5.service层调用推送消息方法

@Service
public class WebSocketHandler {@Resourceprivate WebSocketClient webSocketClient;public boolean sendMessageOne(String userId,String content) {boolean flag = webSocketClient.sendToOne(userId,content);return flag;}
}

6.controller层逻辑

@PostMapping("/send")public Map push2(@RequestBody PushDTO pushDTO){Map map = new HashMap();//1、参数校验,非空~if(StringUtils.isEmpty(pushDTO.getMessage()) || pushDTO.getUserId() == null || pushDTO.getPushType() == null )    {log.info("【消息推送】 参数异常");map.put("code","-1");map.put("msg","参数异常");return map;}//2、推送消息boolean flag = webSocketHandler.sendMessageOne(pushMessage.getUserId() + "", content);//3、如果推送成功,修改状态,返回正确的JSONif(flag){PushMessage updatePushMessage = new PushMessage();updatePushMessage.setId(pushMessage.getId());updatePushMessage.setPushState(PUSH_SUCCESS);
//            pushMessageService.updateById(updatePushMessage);map.put("code","200");map.put("msg","成功");return map;}//4、返回用户未上线的JSONmap.put("code","500");map.put("msg","用户离线");return map;}

http://www.lryc.cn/news/465182.html

相关文章:

  • docker如何建立本地私有仓库,并将docker镜像推到私有仓库
  • vllm启动大语言模型时指定chat_template
  • 网络相关(HTTP/TCP/UDP/IP)
  • TF卡长期不用会丢失数据吗?TF卡数据恢复容易吗?
  • Flink状态一致性保证
  • 前端一键复制解决方案分享
  • 麒麟操作系统swap使用率过高的排查思路
  • 爬虫python=豆瓣Top250电影
  • 【Eclipse系列】解决Eclipse中xxx.properties文件中文乱码问题
  • mysql主从复制及故障修复
  • 基于springboot的网上服装购物商城系统
  • aws(学习笔记第六课) AWS的虚拟私有,共有子网以及ACL,定义公网碉堡主机子网以及varnish反向代理
  • 接口测试(三)jmeter——连接mysql数据库
  • 双十一购物节有哪些好物值得入手?2024双十一好物清单合集分享
  • jmeter中请求参数:Parameters、Body Data的区别
  • Docker安装ActiveMQ镜像以及通过Java生产消费activemq示例
  • 迅为RK3562开发板/核心板240PIN引脚全部引出,产品升级自如
  • C++实现顺序栈和链栈操作(实验3--作业)
  • 龙兴物联一体机:设备监测的智能先锋
  • KinectDK相机SDK封装Dll出现k4abt_tracker_create()创建追踪器失败的问题
  • Linux 命令—— ping、telnet、curl、wget(网络连接相关命令)
  • 高速缓冲存储器Cache是如何工作的、主要功能、高速缓冲存储器Cache和主存有哪些区别
  • 极简版Java敏感词检测SDK
  • H3C路由器交换机操作系统介绍
  • 【项目案例】-音乐播放器-Android前端实现-Java后端实现
  • EasyX图形库的安装
  • 数据结构 - 队列
  • 基于springboot美食推荐商城的设计与实现
  • React开发一个WebSocket
  • Oracle DECODE 丢失时间精度的原因与解决方案