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

【Azure Relay】记录使用Azure Relay在通信中遇见侦听器(Listener)或发送端(Sender)断开时的异常日志 (Hybrid Connection by Websocket)

它是一种单对单的通信方式,需要对服务端和客户端代码有一些改动才可以,需要定义服务端侦听器(Listener)来接受消息,客户端(Caller)来发送消息。

  • 服务端侦听器(Listener): 使用 HybridConnectionListener 对象来初始化对象
  • 客户端发送者(Caller):使用 HybridConnectionClient 对象来初始化对象

Azure Relay的工作原理如下

原理图:

流程说明:

  1. Listening client sends a listening request to the Azure Relay service. The Azure load balancer routes the request to one of the gateway nodes.
  2. The Azure Relay service creates a relay in the gateway store.
  3. Sending client sends a request to connect to the listening service.
  4. The gateway that receives the request looks up for the relay in the gateway store.
  5. The gateway forwards the connection request to the right gateway mentioned in the gateway store.
  6. The gateway sends a request to the listening client for it to create a temporary channel to the gateway node that's closest to the sending client.
  7. The listening client creates a temporary channel to the gateway that's closest to the sending client. Now that the connection is established between clients via a gateway, the clients can exchange messages with each other.
  8. The gateway forwards any messages from the listening client to the sending client.
  9. The gateway forwards any messages from the sending client to the listening client.

基于以上的理解,当Listener 或 Caller 都突然中断的时候, Listener端会记录什么异常日志呢?Caller端会记录什么异常日志呢?

问题解答

第一部分:Caller端异常退出的情况, Listener会记录什么日志呢?

结果

在Listener的日志中,会输出如下的错误消息。

如果不对异常进行处理,会导致整个进程奔溃,Listener退出。

Exception in processing connection: Microsoft.Azure.Relay.RelayException: The remote party closed the WebSocket connection without completing the close handshake. TrackingId:xxx-xx-xx-xx-xxxx4_G8_G9, Address:sb://xxxxxxxx.servicebus.chinacloudapi.cn/xxxxxxxt01, Timestamp:5/17/2026 8:48:56 AM ---> System.Net.WebSockets.WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. at System.Net.WebSockets.WebSocketBase.WebSocketOperation.<Process>d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Net.WebSockets.WebSocketBase.<ReceiveAsyncCore>d__45.MoveNext() --- End of stack trace from previous location where exception was thrown ---

实验

分别启动Listener 和 Caller,在正常通信两次后,直接关闭Caller窗口

第二部分:Listener端异常退出的情况, Caller会记录什么日志呢?

结果

在Caller的日志中,会输出如下的错误消息。

Microsoft.Azure.Relay.RelayException: The remote party closed the WebSocket connection without completing the close handshake. TrackingId:xxxx-x-x-xx-xxxx5e79e2e, Address:sb://xxxxxx.servicebus.chinacloudapi.cn/xxxxxxst01, Timestamp:5/17/2026 9:29:11 AM ---> System.Net.WebSockets.WebSocketException: The remote party closed the WebSocket connection without completing the close handshake. at System.Net.WebSockets.WebSocketBase.WebSocketOperation.<Process>d__19.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Net.WebSockets.WebSocketBase.<ReceiveAsyncCore>d__45.MoveNext()

实验

分别启动Listener 和 Caller,在正常通信后,直接关闭Listener窗口

对比两种情况下的日志,都是Microsoft.Azure.Relay.RelayException: The remote party closed the WebSocket connection without completing the close handshake.

微小的区别在异常消息中的TrackingId格式不同:

  • 如果是Caller异常断开,TrackingId中会携带 _GX_GX 标识,比如: TrackingId:xxx-xx-xx-xx-xxxx4_G8_G9
http://www.jsqmd.com/news/1153464/

相关文章:

  • 算法学习 Agent 的上下文记忆设计:别让每次对话都从零开始
  • 终极指南:如何在macOS上免费安装360Controller驱动,完美支持Xbox游戏手柄
  • 深度学习估计配分函数 —— 退火重要采样 AIS(九十七)
  • Attention U-Net PyTorch 实战:3步集成Attention Gate,医学图像分割Dice提升5%
  • 变压器油位和油质那些事(二)
  • 番茄小说本地化保存终极方案:fanqienovel-downloader让你的阅读永不中断
  • WebAssembly 上的 AI 推理:WasmEdge 与 WASI-NN 的端侧部署方案与性能剖析
  • 独立开发者效率工具链:从需求管理到部署的一人全栈工作流设计
  • Kimi LeetCode 3515. 带权树中的最短路径 Python3实现
  • 用 Cursor 规则文件统一团队编码规范:从约定到强制的工程实践
  • Claude Code与Vibecoding实战指南:从零构建AI编程助手工作流
  • Citrus:Java 集成测试的老牌框架
  • HTML初相识:从零搭建网页结构
  • React useMemo/useCallback 的滥用重灾区与正确使用边界
  • 深度学习图像去噪革命:DnCNN-PyTorch实战指南
  • 脑电入门(一)
  • 终极指南:GitHub工作流魔法将Linux应用移植到iOS世界
  • 智能游戏本地化实战:XUnity自动翻译器深度配置指南
  • 日常居家小酌选什么养生酒?复盛公六味地黄酒口感解析
  • Gitleaks实战指南:构建代码敏感信息自动化检测与防护体系
  • 如何通过ViGEmBus解决Windows游戏控制器兼容性问题:终极技术方案
  • ESP32双路FOC驱动技术深度解析:从设计哲学到工业实战完整指南
  • LangChain 学习笔记(二):Tool Calling、ToolMessage 与结构化输出到底怎么串起来
  • S7-200 SMART V3.0 以太网下载:3种IP配置方法与4步物理连接排查
  • CAD字体缺失的技术挑战与FontCenter自动化管理解决方案
  • FontCenter终极指南:3分钟解决AutoCAD字体缺失的完全免费方案
  • Certum 开源代码签名证书 2024 申请实战:个人身份+开源项目 7 步验证指南
  • 2026企业宽带公司热门排名 小微企业避坑指南整理
  • 柯尔嫚头面妆模式系统开发
  • Reset Windows Update Tool终极指南:3分钟修复Windows更新卡死问题