SignalR中的重连机制和心跳监测机制详解

2024-04-26 22:04

本文主要是介绍SignalR中的重连机制和心跳监测机制详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一. 重连机制

声明:
  本节仅介绍重连机制和心跳监测机制,基于Core 3.1框架,至于SignalR其它的一些基本使用,包括引入、Hub、配置等常规操作,在本节中不介绍,后续写Core下的SignalR

  1. 说明
      默认是没有重连机制的,需要加上withAutomaticReconnect开启重连,默认重连4次,分别时间间隔为:0、2、10和30秒 (指掉线的瞬间马上重连、再过2s重连、再过10s重连,再过20s重连,这里指的是间隔,而不是叠加)。当然也可以自行配置,eg:.withAutomaticReconnect([10000, 4000, 10000, 10000])。

PS: 经过测试,这里有一个现象,比如 先断网,触发掉线机制,然后恢复网,走重连机制,恢复后的重连的第一次是连不上的,必须第二次才能连上。第一次报错:'Error: WebSocket closed with status code: 1006 ().

//安卓手机的写法
var connection = new signalR.HubConnectionBuilder().withUrl("http://47.92.198.126:8088/chathub").withAutomaticReconnect([10000, 4000, 10000, 10000]).build();    
//苹果的手机的写法 (需要跳过协商)          
var connection = new signalR.HubConnectionBuilder().withUrl("http://47.92.198.126:8088/chathub", {skipNegotiation: true, //针对webSocket为默认协议的时候,可以跳过协商transport: signalR.HttpTransportType.WebSockets}).withAutomaticReconnect([3000, 4000, 10000, 10000]).build();

我们发现上述代码,安卓和IOS写法不一样,这里是因为IOS系统仅支持WebSocket协议,所以要手动指定,并且跳过协商。
2. 重连的回调

(1). onreconnecting:重连之前调用 (只有在掉线的一瞬间,只进入一次),状态为:Reconnecting 。

(2). onreconnected:(默认4次重连),任何一次只要回调成功,调用,状态为:Connected 。

(3). onclose:(默认4次重连) 全部都失败后,调用,状态为:Disconnected。

  1. 实战测试

分析下面代码,建立连接后,手机断网,输出1,进入了 onreconnecting 回调;大约过 3s 后,连接上网,即已经过了第一次重连的时间,进入第2个 4s的重连,过了4s,走重连机制,这个时候属于恢复网络后的第一次,是重连不上的,需要到了第三个重连机制,再过10s后,重连成功。

如果一直断网,4次重连全部失败,则会进入onclose回调。

<html><head><meta charset="utf-8"><meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /><title></title><script src="js/jquery.js" type="text/javascript" charset="utf-8"></script><script src="js/signalr.js" type="text/javascript" charset="utf-8"></script><script type="text/javascript">$(function() {//苹果的手机的写法 (需要跳过协商)               var connection = new signalR.HubConnectionBuilder().withUrl("http://XXX:8088/chathub", {skipNegotiation: true, //针对webSocket为默认协议的时候,可以跳过协商transport: signalR.HttpTransportType.WebSockets}).withAutomaticReconnect([3000, 4000, 10000, 10000]).build();            //建立连接$('#j_btn1').click(function() {connection.start().then(function() {console.log("连接成功");$('#j_hb').append('<div>连接成功</div>')}).catch(function(err) {$('#j_hb').append('<div>' + err.toString() + '</div>')return console.error(err.toString());});});//发送消息$("#j_send").click(function() {connection.invoke("SendMessage", $("#j_content").val()).catch(function(err) {$('#j_hb').append('<div>' + err.toString() + '</div>');return console.error(err.toString());});});//接收消息connection.on("ReceiveMessage", function(msg) {console.log(msg);$('#j_hb').append('<div>' + msg + '</div>')});//下面测试断线重连机制 ,//重连之前调用 (只有在掉线的一瞬间,只进入一次)connection.onreconnecting((error) => {console.log(1);$('#j_hb').append('<div>1</div>');console.log(connection.state);console.log(connection.state === signalR.HubConnectionState.Reconnecting);});//(默认4次重连),任何一次只要回调成功,调用connection.onreconnected((connectionId) => {console.log(2);$('#j_hb').append('<div>2</div>');console.log(connection.state);console.log(connection.state === signalR.HubConnectionState.Connected);});//(默认4次重连) 全部都失败后,调用connection.onclose((error) => {console.log('3');$('#j_hb').append('<div>3</div>');console.log(connection.state);console.assert(connection.state === signalR.HubConnectionState.Disconnected);});});</script></head><body><br /> <br /> <br /> <br /> <br /><input type="text" id="j_content" value="" /><button id="j_btn1">建立连接</button><button id="j_send">发送消息</button><br /> <br /> <br /> <br /> <br /><div id="j_hb"></div></body>
</html>

二. 心跳监测机制

  1. 何为心跳监测机制

当客户端和app端不发送消息的时候,这个时候需要一种机制,来相互ping,保证客户端和服务器端是连接状态的,从而一直保证在线状态哦。这里有两套机制来保证,分别是告诉客户端,服务器是正常的;告诉服务器端,客户端是在线的。SignalR提供了两套监测机制,来保证长久连接在线不掉,或者删掉不必要的客户端,释放资源。

2. 配置说明

(1). 服务端配置

在这里插入图片描述
A. clientTimeoutInterval:表示客户端如果在30s内没有向服务器发送任何消息,那么服务器端则会认为客户端已经断开连接了,则进入OnDisconnectedAsync方法, 但实际上 客户端此时可能并没有断开连接,或者断开连接还需要一段时间,因为客户端断开连接是走的另外一套机制的。【以服务器端为基准,判断客户端是否断开连接,从而断开服务器端连接】
B. keepAliveinterval: 表示如果服务器未在15s内向客户端发送消息,在15s的时候服务器会自动ping客户端,是连接保持打开的状态。【用于控制服务端自动ping客户端的时间】
(2). 客户端配置
在这里插入图片描述
 A. serverTimeoutInMilliseconds:表示客户端如果在30s内收到服务器端发送的消息,客户端会断开连接,进入onclose事件。(前提是没有启动:自动重连机制,已测试)。 它和服务器端的keepAliveinterval是一对的,该值必须比服务器端的serverTimeoutInMilliseconds值大,建议是它的两倍。【是以客户端为基准,判断服务器端是否断开连接,从而断开客户端连接】

B. keepAliveIntervalInmillisecods:【用户控制客户端自动ping服务器端的时间】。 指如果客户端在15s内没有发送任何消息,则15s的时候客户端会自动ping一下服务器端,从而告诉服务器端,我在线。如果15s内发消息,这个时间间隔将会被重置。

(3). 两套机制 (实际中,两套机制相互配合使用)

A. 以客户端为基准的机制 (客户端主动进 onclose回调)

客户端配置:serverTimeoutInMilliseconds + 服务端端配置:keepAliveinterval ,建议serverTimeoutInMilliseconds 的值是 keepAliveinterval 的两倍,从而保证客户端不进入 onclose回调,不掉线。

代码分享:下面代码的配置就是默认配置,客户端配置30s没有收到服务器端发过来的信息,则认为服务器端异常,客户端掉线,进入onclose回调;服务器端配置为15s没有向客户端发送消息,则需要主动ping一下客户端,按照默认这种Server 15s,Client 30s的配置,在网络通畅的情况下,客户端是不会掉线的。

PS:此处如果改个非正常配置,比如客户端 serverTimeoutInMilliseconds 配置10s,服务器端
keepAliveInterval 配置20s,经测试,你会发现,如果客户端在10s内没有收到任何消息,则会吊销,进入onclose回调。

public void ConfigureServices(IServiceCollection services){services.AddControllersWithViews();//此处是做SignalR的全局配置,也可以去下面的集线器出配置单独的,单独的优先级> 此处全局的services.AddSignalR(hubOptions =>{       //服务器端向客户端 ping的间隔hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(15);});}

B. 以服务端为基准的机制

客户端配置:keepAliveIntervalInmillisecods + 服务端配置:clientTimeoutInterval,建议 clientTimeoutInterval 的值是 keepAliveIntervalInmillisecods 的两倍,从而保证不进服务器端的 OnDisconnectedAsync 回调,即不掉线。

代码分享:下面代码是默认配置,客户端配置15s内没有向服务器发送任何消息,则自动ping一下服务器端;服务器端配置30s没有收到客户端发送的消息,则认为客户端已经掉线(虽然客户端此时可能没有掉线);在网络通畅的情况下,服务器端是不会进入OnDisconnectedAsync回调的。

var connection = new signalR.HubConnectionBuilder().withUrl("http://XXXX:8088/chathub").build();    
connection.keepAliveIntervalInMilliseconds= 15000;  //15s
public void ConfigureServices(IServiceCollection services){services.AddControllersWithViews();//此处是做SignalR的全局配置,也可以去下面的集线器出配置单独的,单独的优先级> 此处全局的services.AddSignalR(hubOptions =>{       //要求30s内必须收到客户端发的一条消息,如果没有收到,那么服务器端则认为客户端掉了hubOptions.ClientTimeoutInterval= TimeSpan.FromSeconds(30);});}

在这里插入图片描述

这篇关于SignalR中的重连机制和心跳监测机制详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/938775

相关文章

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

前端高级CSS用法示例详解

《前端高级CSS用法示例详解》在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交互和动态效果的关键技术之一,随着前端技术的不断发展,CSS的用法也日益丰富和高级,本文将深... 前端高级css用法在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使