位置: 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)

  • 华为p40的屏幕刷新率是多少呢(华为p40的屏幕刷新率高吗)

    华为p40的屏幕刷新率是多少呢(华为p40的屏幕刷新率高吗)

  • 剪映删除的视频要如何恢复(剪映删除的视频怎么找回没有云备份)

    剪映删除的视频要如何恢复(剪映删除的视频怎么找回没有云备份)

  • qq需不需要实名认证吗(qq是否要实名认证)

    qq需不需要实名认证吗(qq是否要实名认证)

  • 笔记本电脑最大内存是多少g(笔记本电脑最大支持容量是什么意思)

    笔记本电脑最大内存是多少g(笔记本电脑最大支持容量是什么意思)

  • 重命名是什么意思(重命名是啥)

    重命名是什么意思(重命名是啥)

  • 微信可以有多少好友(微信可以有多少好友上限)

    微信可以有多少好友(微信可以有多少好友上限)

  • 电脑wps是什么意思(电脑上wps2019是什么意思)

    电脑wps是什么意思(电脑上wps2019是什么意思)

  • 键盘另起一行是哪个键(键盘打字另起一行)

    键盘另起一行是哪个键(键盘打字另起一行)

  • 苹果11充满电需要多久(苹果11充满电需要多少电费)

    苹果11充满电需要多久(苹果11充满电需要多少电费)

  • 计算器的on/c起什么作用(计算器on/c的功能是什么)

    计算器的on/c起什么作用(计算器on/c的功能是什么)

  • 华为荣耀6plus是不是双卡双待(华为荣耀6plus是什么型号)

    华为荣耀6plus是不是双卡双待(华为荣耀6plus是什么型号)

  • 为什么在快手设置里找不到我的钱包(为什么在快手设置的壁纸没有声音)

    为什么在快手设置里找不到我的钱包(为什么在快手设置的壁纸没有声音)

  • ipad11是什么型号(ipad11是啥)

    ipad11是什么型号(ipad11是啥)

  • ipadmini有插卡版吗(ipad mini插卡版什么时候发售)

    ipadmini有插卡版吗(ipad mini插卡版什么时候发售)

  • iphone进水充不进去电怎么办(iphone进水充不进去电可以用冷风吹吗)

    iphone进水充不进去电怎么办(iphone进水充不进去电可以用冷风吹吗)

  • 怎样把qq相册传到微信(怎样把qq相册传到电脑上)

    怎样把qq相册传到微信(怎样把qq相册传到电脑上)

  • word2003稿纸设置在哪(word2016稿纸设置)

    word2003稿纸设置在哪(word2016稿纸设置)

  • 抖音短视频怎么设锁屏(抖音短视频怎么做才有播放量)

    抖音短视频怎么设锁屏(抖音短视频怎么做才有播放量)

  • 微信标题怎么设置(微信标题怎么设置正中间)

    微信标题怎么设置(微信标题怎么设置正中间)

  • 开免打扰模式有什么用(免打扰模式会有声音吗)

    开免打扰模式有什么用(免打扰模式会有声音吗)

  • pr怎么裁剪视频画面大小(pr怎么裁剪视频边框)

    pr怎么裁剪视频画面大小(pr怎么裁剪视频边框)

  • 华为mate20保时捷和普通版区别

    华为mate20保时捷和普通版区别

  • 校园网忘记密码怎么找回(校园网忘记密码怎么搞)

    校园网忘记密码怎么找回(校园网忘记密码怎么搞)

  • oppor17网速慢怎么调(oppor174g网络慢是什么原因)

    oppor17网速慢怎么调(oppor174g网络慢是什么原因)

  • 西瓜视频如何同步抖音

    西瓜视频如何同步抖音

  • 如何查看电脑是什么系统?(如何查看电脑是什么牌子)

    如何查看电脑是什么系统?(如何查看电脑是什么牌子)

  • 【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定(vue2-elm)

    【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定(vue2-elm)

  • GPT-4:关于下一代人工智能模型的事实、谣言和期望

    GPT-4:关于下一代人工智能模型的事实、谣言和期望

  • 公司缴税怎么计算的
  • 小规模纳税人的企业所得税税率
  • 企业所得税季度申报
  • 物业公司物业费不开发票
  • 建设部门罚款会计分录
  • 库存商品发出汇总表
  • 残次品销售账务处理
  • 纳税人等级怎么划分
  • 企业的两金是哪两金
  • 企业退回企业所得税分录
  • 代开的增值税专用发票应怎样填写?
  • 一般纳税人辅导期
  • 个人劳务发票怎么交税
  • 计提坏账准备和冲减坏账准备
  • 财政收回项目资金的整改报告
  • 17%增值税发票怎么计算成13%
  • 内部部门汇缴上级财务
  • 品种法完工产品成本的单位成本怎么算
  • 小规模企业营业税
  • 个体工商户季度不超过30万免增值税吗
  • 手撕票验旧是什么意思
  • 收承兑汇票还要交税吗
  • 人力资源顾问公司有什么岗位
  • 如何判断境内企业所得税
  • 卖仪表赚钱吗
  • 企业所得税多交了必须退税吗
  • 不动产处置流程
  • 消耗性生物资产与生产性生物资产的区别
  • 安装服务需要预缴税款吗
  • win10 microsoft store怎么改变下载途径
  • 银行存款日记账怎么记账
  • 个体工商户核定征收标准2023
  • windows10安装应用怎么到桌面
  • 公司收到加盟费怎么做会计分录
  • linux docx
  • 债转股是好还是坏
  • php递归算法经典实例
  • 代扣的工会会费怎么做账
  • Win11错误提示"the pc must support secure boot"怎么解决
  • 根据新企业所得税法的规定,企业购买并实际使用
  • 怎么登明细分类账
  • win10不关机设置方法
  • elementui ts
  • 同业代付会计分录
  • 已计提的存货跌价准备计入成本吗
  • php 跨域
  • icse论文
  • 应收账款结账损失怎么算
  • 公司加班餐费会计科目
  • 增值税申报销项发票采集少了怎么办
  • switch关键账号教程
  • micro start
  • 运费发票有普票吗
  • 网银转账往来款怎么做账
  • access字符型数据
  • 没进项发票的开销项发票多少税?
  • 注册资金只能增加不能减少吗
  • 发票入账的管理规定
  • 预支差旅费怎么记账
  • 预付账款为什么属于资产类
  • 委托付款做账怎么做
  • 出售设备账务处理
  • 已经计提的坏账收回了怎么做
  • 预付工资怎么入账
  • 出售短期债券投资发生的净损失计入哪里
  • mysql中一个普通ERROR 1135 (HY000)错误引发的血案
  • ubuntu server怎么样
  • linux如何关闭selinux
  • 一起回顾一下本周我们的读书生活
  • linux系统命令包含在哪个目录中
  • 狗刨教学视频新手入门
  • glsurfaceview特性
  • 根据安全生产法的规定,生产经营单位
  • 利用职务之便谋取私利是什么罪
  • tiles框架
  • 深入理解新发展理念,推进供给侧结构性改革 心得体会
  • 广州地税电子税票查询
  • 演艺明星
  • 医院盖章去哪个部门
  • 服务行业工作总结不足
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设