1.此 Demo 服务端环境: .NET Core 2.2,WebAPI, 客户端环境: 类库 EF4.7.2, 应用场景:以客户端为基础的连接机制,客户端的 ServerTimeout 最好是 服务端 KeepAliveInterval 的两倍
2.所用到的机制: 重连机制,心跳机制
3.服务端代码:
Startup.cs 文件添加
public void ConfigureServices(IServiceCollection services)
{
//添加SignalR应用
services.AddSignalR(hubOptions =>
{
hubOptions.KeepAliveInterval = System.TimeSpan.FromSeconds(15);
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//配置SignalR路由(注意:写在 app.UseMvc 前面)
app.UseSignalR(route =>
{
route.MapHub<MessageHub>("/MessageHub");
});
app.UseMvc();
}
建立HUB
public class MessageHub : Hub<IMyClass>
{
private string GroupName = "MyGroupName";
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, GroupName);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, GroupName);
await base.OnDisconnectedAsync(exception);
}
/// <summary>
/// 服务端向客户端发送消息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task SendMessage(Guid id)
{
try
{
await Clients.Group(GroupName).TriggerEvent(id);
}
catch
{
}
}
}
public interface IMyClass
{
//客户端定义的方法名也必须和这个方法名一样,包括签名.
Task TriggerEvent(Guid id);
}
建立MyHubController
[ApiController]
public class MyHubController : ControllerBase
{
private readonly IHubContext<MessageHub, IMyClass> _hubContext;
public SyncHubController(IHubContext<MessageHub, IMyClass> hubContext)
{
_hubContext = hubContext;
}
[HttpGet]
[Route("api/MyHub/TriggerEvent")]
public void TriggerEvent(Guid id)
{
try
{
_hubContext.Clients.All.TriggerEvent(id);
}
catch { }
}
}
4.客户端代码:
public class ClientSignalRClass
{
Guid id;
HubConnection hubConnection;
public ClientSignalRClass(Guid id)
{
this.id= id;
}
public async Task ConnectSignalRServerAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(ClientSignalRConfig.API_URL_Hub)
.WithAutomaticReconnect(new[] { TimeSpan.FromSeconds(0),TimeSpan.FromSeconds(2),TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(10),TimeSpan.FromSeconds(30)
})
.Build();
//连接服务超时时间
hubConnection.ServerTimeout = TimeSpan.FromSeconds(30);
//重连回调
hubConnection.Reconnecting += hubConnection_Reconnecting;
hubConnection.Reconnected += hubConnection_Reconnected;
hubConnection.Closed += hubConnection_Closed;
//TriggerClientSyncBalance事件名称与服务端一致
hubConnection.On<Guid>("TriggerEvent", (x) => DoSomething(x));
await StartConnection();
}
private async Task hubConnection_Closed(Exception arg)
{
try
{
await Task.Delay(TimeSpan.FromMilliseconds(1));
LogHelper.WriteLog(string.Format("{0} {1}", "SignalR Closed:", arg.Message));
}
catch (Exception ex)
{
LogHelper.WriteLog(string.Format("{0} {1} {2}", "SignalR Reconnecting:", arg.Message, ex.Message));
}
}
private async Task hubConnection_Reconnecting(Exception arg)
{
try
{
await Task.Delay(TimeSpan.FromMilliseconds(1));
LogHelper.WriteLog(string.Format("{0} {1}", "SignalR Reconnecting:", arg.Message));
}
catch (Exception ex)
{
LogHelper.WriteLog(string.Format("{0} {1} {2}", "SignalR Reconnecting:", arg.Message, ex.Message));
}
}
private async Task hubConnection_Reconnected(string arg)
{
try
{
await Task.Delay(TimeSpan.FromMilliseconds(1));
LogHelper.WriteLog(string.Format("{0} {1}", "SignalR Reconnected:", arg));
}
catch (Exception ex)
{
LogHelper.WriteLog(string.Format("{0} {1} {2}", "SignalR Reconnected:", arg, ex.Message));
}
}
private async Task StartConnection()
{
try
{
await hubConnection.StartAsync();
LogHelper.WriteLog("SignalR 连接成功");
}
catch (Exception ex)
{
LogHelper.ErrorLog("SignalR 连接失败:", ex);
}
}
private void DoSomething(Guid id)
{
//todo...
}
}