BugReport:前端不能成功解析后端信息造成消息阻塞问题

1 前端不能成功解析后端信息造成消息阻塞问题

文章主要以问题场景复现问题相关概念剖析错误点的定位最终总结为切入点,尽详细介绍此次问题由来与解决。

1.1 问题记录

1.1.1 问题场景复现

初步怀疑:WebSocket与Spring Taskd或者HTTP的冲突

1.1.1.1:问题场景:使用WebSocket让客户端,播报订单相关语音信息时,一句语音总是不能报放完且每隔一段时间一直循环。客户端控制台,一直重复提交数据。
在这里插入图片描述

1.1.2 问题业务开发情况

1.1.2.1:此次业务目的:在客户端实现用户下单号,语音播报“ 有用户下单,请及时处理 ”

1.1.2.2:为确保开发过程中,代码的健壮性,前期使用模拟业务对WS协议中,客户端与服务器交互进行验证,验证代码如下:

@Autowired
private WebSocketServer webSocketServer;

   /**
    * 通过WebSocket每隔5秒向客户端发送消息
    */
   @Scheduled(cron = "0/5 * * * * ?")
   public void sendMessageToClient(){
       webSocketServer.sendToAllClient("这是来自服务端的消息:" +
DateTimeFormatter.ofPattern("HH:mm:ss").form>at(LocalDateTime.now()));
   }

1.1.2.2:之后controller中常规书写,崽业务层实现类中。代码如下:

public void paySuccess(OrdersPaymentDTO ordersPaymentDTO) {
       //取出前端传参订单number
       String orderNumber = ordersPaymentDTO.getOrderNumber();

       //根据订单number查询订单详细
       Orders orders = orderMapper.getByNumber(orderNumber);

       //构建订单状态,支付方式,支付状态,结账时间
       orders = Orders.builder()
               .id(orders.getId())
               .amount(orders.getAmount())
               .payStatus(Orders.PAID)
               .checkoutTime(LocalDateTime.now())
               .number(orderNumber)
               >.status(Orders.TO_BE_CONFIRMED).build();
       //根据订单id更新订单状态
       orderMapper.update(orders);
       log.info("模拟支付完毕");
       Map map = new HashMap<>();
       map.put("type", 1);
       map.put("orderId", orders.getId());
       map.put("content", "订单号:" + orderNumber);
       //map.put("content0", "订单号:" + orderNumber);//content
       >webSocketServer.sendToAllClient(JSON.toJSONString(map));
   }

最终用户完成下单,客户端,发生语音播报循环。

1.2 问题剖析

1.2.1 WebSocket协议

1.2.1.1 WS协议介绍

WebSocket :是基于 TCP 的新网络协议。它实现了浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者间就可以创建持久性的连接, 并进行双向数据传输。

全双工通信:又称双向同时通信,即通信双方可以同时发送和接收信息的信息交互方式。

1.2.1.2 WebSocket缺点

1.服务器长期维护长连接需要一定的成本各个浏览器支持程度不一
2.WebSocket 是长连接,受网络限制比较大,需要处理好重连

1.2.2 HTTP协议

1.2.2.1 HTTP协议介绍

介绍:HTTP协议(超文本传输协议)是一种网络通信协议,允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。默认端口:80

1.2.2.2 HTTP协议和WebSocket协议对比
HTTP 协议WebSocket 协议
HTTP是短连接WebSocket是长连接
HTTP通信是单向的,基于请求响应模式WebSocket支持双向通信

HTTP和WebSocket底层都是TCP连接

1.2.3 Spring Taskd

1.2.3.1 Spring Taskd介绍

介绍:Spring Taskd是Spring框架提供的任务调度工具,可以按照约定时间自动执行某个代码逻辑。

1.2.3.2 Spring Taskd中cron表达式

cron表达式就是一个字符串,通过cron表达式可以定义任务触发时间

构成规则:分为6或7个域,由空格分隔开,每个域代表一个含义
每个域的含义分别为:年(可选)
例如:

cron = "6/6 * * * * ? " //测试:从6开始每6s.执行一次

参考:cron表达式在线生成器

1.3 错误点的定位

1.3.1 controller层debug断点观察小程序端支付接口传参

接收参数无误
在这里插入图片描述

1.3.2 同时管理员浏览器客户端观察控制台输出日志

发现,后端服务一直再给前端响应信息,而我的支付接口还没响应完毕(断点没放行)
在这里插入图片描述

1.3.3 前后端错误总结

可以观察到管理员端,每隔5s中一直再响应数据中,所以定位到后端Task定时任务错误,其次根据日志中信息,得到准确错误处,最终注释cron定义的任务时间,禁止其向客户端响应数据,完成bug修复
在这里插入图片描述
在这里插入图片描述

1.4 观点总结

  • 直接原因同一个webSocketServer中的sendToAllClient方法被调用多次,这是直接导致此次bug出现的原因
  • 直接原因:其次后端使用webStocketServer协议传递的信息前后端已经约定好,当传递前端自定义信息“这是来自服务端的消息时”和语音信息时,@Scheduled(cron = "0/5 * * * * ?"),先是在0~5s解析自定义信息,前端无法正常解析,导致前端控制台报错,其次在5s~10s进行语音播报,但是语音长度>5s,直接导致两次任务方法循环运行,本次bug出现。
  • 深层次WS协议中无多路复用可以考虑此篇不再深入,如关注后继,烦请三连关注。

1.5 参考文章

HTTP 协议的三次握手

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值