位置: IT常识 - 正文

Java使用WebStocket实现前后端互发消息(java使用循环结构输出九九乘法表)

编辑:rootadmin
Java使用WebStocket实现前后端互发消息

推荐整理分享Java使用WebStocket实现前后端互发消息(java使用循环结构输出九九乘法表),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:java使用循环结构输出九九乘法表,java使用while循环对n以内的偶数求和,java使用while循环对n以内的偶数求和,java使用for循环作等腰三角形,java使用正则表达式替换,java使用指定版本的jar包,java使用递归的方法求n!,java使用正则表达式替换,内容如对您有帮助,希望把文章链接给更多的朋友!

记录一下自己使用WebStocket实现服务器主动发消息的过程和踩得雷。

需求:车牌识别系统识别到车牌后,持续向前端推送车牌信息,直到前端回复收到。

测试需求:新增 客户后,持续向前端推送客户信息,直到前端收到消息,并且回复收到。

1.引入WebStocket的依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId><version>2.7.0</version></dependency>

2.创建配置类 WebScoketConfig

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/** * 开启WebSocket支持 */@Configurationpublic class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }}

新增客户的业务层

  这里实现了新增 客户后,持续向前端推送客户信息。

  实现思路:本来是打算 让前端接收到客户信息,回复后端的时候,后端修改数据库中此条客户的 接收状态的字段,然后每次后端往前端发送消息的时候都去数据库查询一次 客户信息的接收状态,如果已经接收到了就不往前端推送。但是好像会造成一边读数据库,一边修改数据库,会出现脏读的问题,而且我在 WebScoketConfigServer 中并不能创建Service层的对象,总是报空指针。

  最后,决定使用 static修饰的静态变量来实现对前端是否接受到消息和是否发送的是同一条重复的消息进行判断。然后根据返回的结果决定是否继续往前端推送消息。

import io.recycle.modules.rest.api.dto.system.CustomerDto;import io.recycle.modules.rest.api.dto.system.CustomerQueryDto;import io.recycle.modules.rest.api.dto.weigh.CardDto;import io.recycle.modules.rest.api.dto.weigh.CustomerParam;import io.recycle.modules.rest.api.dto.weigh.CustomerWeighDto;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;import java.util.Map;import io.recycle.modules.rest.api.dao.RecycleCustomerDao;import io.recycle.modules.rest.api.entity.RecycleCustomerEntity;import io.recycle.modules.rest.api.service.RecycleCustomerService;@Service("recycleCustomerService")public class RecycleCustomerServiceImpl implements RecycleCustomerService{private static int count=0;@Autowiredprivate NoticeWebsocket noticeWebsocket;@Autowiredprivate RecycleCustomerDao recycleCustomerDao;@Overridepublic void save(RecycleCustomerEntity recycleCustomer){recycleCustomerDao.save(recycleCustomer);//测试webstocket,实现新增客户往前端推送消息,直到前端回复////测试webstocketboolean flag = false;do{try {Thread.sleep(300); //休息300毫秒} catch (InterruptedException e) {e.printStackTrace();System.out.println("休息时出错000000");}//往前端发送消息System.out.println("count===="+count);boolean resultFlag = noticeWebsocket.sendMessage("新增了用户:" + recycleCustomer.toString(),count);flag = resultFlag;if (resultFlag){System.out.println("停止往前端发送数据,因为 resultFlag 为: "+resultFlag+"==说明前端已接收的消息");}else {System.out.println("往前端发送数据,因为 resultFlag 为: "+resultFlag+"==说明前端还没接收到消息");}}while ( !flag );System.out.println("停止往前端发送数据,因为 delFlag 为: "+flag);count = count +1;}}

3.创建WebScoketConfigServer

在websocket协议下,后端服务器相当于ws里的客户端,需要用@ServerEndpoint指定访问的路径,并使用@Component注入容器。

这里实现了新增 客户后,持续向前端推送客户信息,直到前端收到消息,并且回复收到。

Java使用WebStocket实现前后端互发消息(java使用循环结构输出九九乘法表)

实现思路:

import com.alibaba.fastjson.JSONObject;import io.recycle.modules.rest.api.dao.RecycleCustomerDao;import io.recycle.modules.rest.api.dto.websocket.NoticeWebsocketResp;import io.recycle.modules.rest.api.entity.RecycleCustomerEntity;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.io.IOException;import java.util.*;import java.util.concurrent.ConcurrentHashMap;/** * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端, * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端 */@ServerEndpoint("/chepaisend")@Component@Slf4jpublic class NoticeWebsocket { //记录连接的客户端 public static Map<String, Session> clients = new ConcurrentHashMap<>(); /** * userId关联sid(解决同一用户id,在多个web端连接的问题) */ public static Map<String, Set<String>> conns = new ConcurrentHashMap<>(); private String sid = null; //一些记录发送消息状态 private static int initFlag =0; private static int tempFlag =0; //区分新旧消息的变量 private static int sum=0; /** * 连接成功后调用的方法 * @param session * */ @OnOpen public void onOpen(Session session) { this.sid = UUID.randomUUID().toString(); clients.put(this.sid, session); log.info(this.sid + "连接开启!"); } /** * 连接关闭调用的方法 */ @OnClose public void onClose() { log.info(this.sid + "连接断开!"); clients.remove(this.sid); } /** * 判断是否连接的方法 * @return */ public static boolean isServerClose() { if (NoticeWebsocket.clients.values().size() == 0) { log.info("已断开"); return true; }else { log.info("已连接"); return false; } } /** * 发送给所有用户 * @param noticeType */ public static boolean sendMessage(String noticeType,int count){ //判断是否是新的新增客户 System.out.println("count= "+count+",sum= "+sum+",initFlag= "+initFlag+",tempFlag= "+tempFlag); if (sum != count){ NoticeWebsocketResp noticeWebsocketResp = new NoticeWebsocketResp(); noticeWebsocketResp.setNoticeType(noticeType); sendMessage(noticeWebsocketResp); sum = count; } //判断前端是否 回复了 收到消息 相等没收到,不相等 收到 if (initFlag==tempFlag){ NoticeWebsocketResp noticeWebsocketResp = new NoticeWebsocketResp(); noticeWebsocketResp.setNoticeType(noticeType); sendMessage(noticeWebsocketResp); }else { //收到消息了,别发同一个消息了 tempFlag = initFlag; return true; } tempFlag = initFlag; //没收到消息继续发 return false; } /** * 发送给所有用户 * @param noticeWebsocketResp */ public static void sendMessage(NoticeWebsocketResp noticeWebsocketResp){ String message = JSONObject.toJSONString(noticeWebsocketResp); for (Session session1 : NoticeWebsocket.clients.values()) { try { session1.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } /** * 根据用户id发送给某一个用户 * **/ public static void sendMessageByUserId(String userId, NoticeWebsocketResp noticeWebsocketResp) { if (!StringUtils.isEmpty(userId)) { String message = JSONObject.toJSONString(noticeWebsocketResp); Set<String> clientSet = conns.get(userId); if (clientSet != null) { Iterator<String> iterator = clientSet.iterator(); while (iterator.hasNext()) { String sid = iterator.next(); Session session = clients.get(sid); if (session != null) { try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } } } } } /** * 收到客户端消息后调用的方法 * @param message * @param session */ @OnMessage public void onMessage(String message, Session session) { log.info("收到来自窗口"+"的信息:"+message); if ("已接收到消息".equals(message)){ //收到消息,改变flag的值 System.out.println("前端已经收到消息,开始改变 initFlag的值,此时initFlag= "+initFlag); initFlag = initFlag +1; System.out.println("前端已经收到消息,已经改变 initFlag的值,此时initFlag== "+initFlag); } } /** * 发生错误时的回调函数 * @param error */ @OnError public void onError(Throwable error) { log.info("错误"); error.printStackTrace(); }}

封装的发送消息的对象

import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;@Data@ApiModel("ws通知返回对象")public class NoticeWebsocketResp<T> { @ApiModelProperty(value = "通知类型") private String noticeType; @ApiModelProperty(value = "通知内容") private T noticeInfo;}

4.WebSocket调用

用户端调用此接口,主动将消息发送给后端,后端接收到消息后再主动推送给指定/全部用户,可以实现消息的私聊和群发功能。

import io.recycle.common.utils.R;import io.recycle.modules.rest.api.service.impl.NoticeWebsocket;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/order")public class OrderController {@GetMapping("/test") public R test() { NoticeWebsocket.sendMessage("你好,WebSocket",1); return R.ok(); }}

前端WebSocket连接

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SseEmitter</title></head><body><div id="message"></div></body><script> var limitConnect = 0; init(); function init() { //开启webstocket服务的ip地址 ws:// + ip地址 + 访问路径 var ws = new WebSocket('ws://127.0.0.1:8191/double-win/chepaisend');// 获取连接状态 console.log('ws连接状态:' + ws.readyState);//监听是否连接成功 ws.onopen = function () { console.log('ws连接状态:' + ws.readyState); limitConnect = 0; //连接成功则发送一个数据 ws.send('我们建立连接啦'); }// 接听服务器发回的信息并处理展示 ws.onmessage = function (data) { console.log('接收到来自服务器的消息:'); console.log(data); //接收到 消息后给后端发送的 确认收到消息,后端接收到后 不再重复发消息 ws.send('已接收到消息'); //完成通信后关闭WebSocket连接 // ws.close(); }// 监听连接关闭事件 ws.onclose = function () { // 监听整个过程中websocket的状态 console.log('ws连接状态:' + ws.readyState); reconnect(); }// 监听并处理error事件 ws.onerror = function (error) { console.log(error); } } function reconnect() { limitConnect ++; console.log("重连第" + limitConnect + "次"); setTimeout(function(){ init(); },2000); }</script></html>

项目启动后,打开写好的前端页面后控制台打印连接信息

 新增客户后,前端接收到,并回复收到了

  新增客户后,前端接收到,并回复收到了,后端停止推送

前端接收到,但是骗后端没收到,或者说后端不知道 前端已经接收到消息。 

后端展示,后端一直往前端推送

 

本文链接地址:https://www.jiuchutong.com/zhishi/298859.html 转载请保留说明!

上一篇:css深度选择器deep(css选择器nth)

下一篇:睿智的目标检测——PyQt5搭建目标检测界面(睿智目标检测yolov8)

  • 小规模纳税人税收优惠2023
  • 小规模纳税人税控系统
  • 小规模纳税人月超10万季度不超30万
  • 成本 费用区别
  • 股权转让需要开董事会吗
  • 清产核资与清算的关系
  • 电子税务局在哪里看财务报表
  • 拆迁补偿款上交财政
  • 国外人员劳务费怎么算
  • 奖金计提发放会计分录
  • 年底增值税专用发票入帐不勾选抵扣帐务处理
  • 收购粮食怎么做账
  • 个人所得税成本费用包括哪些
  • 公司投资股票要交什么税
  • 外地职工医保怎么报销
  • 本月没开发票怎样报税
  • 营业执照原件丢失后果
  • 个人股东分红如何合理避税
  • 收到美金货款
  • 进口增值税可以抵扣销项税额吗
  • mac如何配置
  • 上个月的流量这个月可以用吗
  • 企业合并中或有负债确认后期调整的项目
  • 本月暂估成本的会计分录
  • 中专学历可以报成人本科吗
  • antd怎么用
  • 最常用的成本核算方法表
  • 劳务报酬个人所得税税率表2023
  • php正则替换字符串
  • 很值得收藏
  • 基于yolov5的目标检测实验任务
  • php操作json文件
  • opencv教程
  • 误餐补助所得税处理
  • 提取公益金会计怎么做账
  • php实现站内消息推送
  • 数据结构—python语言描述
  • dedecms转其他cms
  • 专利银行汇款操作步骤
  • 资产处置损益影响损益吗
  • 注册资本认缴制的利弊
  • 余利宝本金会亏吗
  • 购进生产车间增值税税率
  • 为什么借贷平台借不到钱了
  • 备用金怎么计入明细账
  • 建筑安装合同印花税率怎么算
  • 发票跨年红冲 交税
  • 质量赔款能冲减收入么
  • 发票没交税可以报销吗
  • 公司财务部门工作职责
  • 小公司用什么财务软件做账
  • 残保金怎么办理
  • 存储过程的定义及调用方法
  • linux系统关机重启命令
  • virtualbox?
  • solaris syslog
  • win2003系统要求
  • linux搭建gitlab
  • 安装solaris11
  • bois开启usb功能
  • task hots windows
  • scrtkfg.exe - scrtkfg是什么进程 有什么用
  • 各种linux系统比较
  • win8系统触摸板按键不能用
  • python爬取教程
  • node.js模块化
  • css优化提高性能的方法有哪些
  • perl 数组放入另一个数组
  • opengl 函数可以在子线程中调用吗
  • python 入门
  • nodejs 调用命令行
  • node 创建文件夹
  • rpg好玩地图
  • bootstrapped 5%
  • 基于javascript的毕业设计
  • python安装基础教程
  • jquery 获取屏幕高度
  • 纳税人对税务机关做出的征税行为不服的,必须
  • 广东省地税局网上办税
  • 税控机怎么开发票
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设