写点什么

SignalR Core 之 Hubs 基本概念

发布于: 2020 年 06 月 11 日

Hubs可以做什么



  1. 实时调用已经连接的任意客户端的Function

  2. 如果与RPC的概念做对比的话,SignalR更像是RFC(远程函数调用)



配置Hubs



首先注册signalr service。



services.AddSignalR();



配置中间件



app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ChatHub>("/chathub");
});



创建对应的Hubs



创建一个公有类ChatHub,继承Hub。这个类里面实现的公有方法都可以被已经连接的客户端调用。



public class ChatHub : Hub
{
public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
}



需要注意的是Hub的实例化是由SignalR框架来控制的,而且在达到一定规模后,Hubs的部署一定是分布式的,所以切记将Hubs保持为无状态模式。



重要的结构



Context



成员



方法



Clients



成员



方法



RFC示例



ReceiveMessage是客户端已经实现的函数



public Task SendMessage(string user, string message)
{
return Clients.All.SendAsync("ReceiveMessage", user, message);
}
public Task SendMessageToCaller(string message)
{
return Clients.Caller.SendAsync("ReceiveMessage", message);
}
public Task SendMessageToGroup(string message)
{
return Clients.Group("SignalR Users").SendAsync("ReceiveMessage", message);
}



RFC约束



上个例子中,远程调用的函数是以字符串的形式来表示的,灵活性有余,但是正确性和一致性不足,增加函数约束来解决次问题。



// 定义RFC约束
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
Task ReceiveMessage(string message);
}
// 增加RFC编译时检查
public class ChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
await Clients.All.ReceiveMessage(user, message);
}
public Task SendMessageToCaller(string message)
{
return Clients.Caller.ReceiveMessage(message);
}
}



事件Hook



目前Hubs针对客户端的连接和断开事件提供了Hook,只需要重载OnConnectedAsyncOnDisconnectedAsync即可



// 需要注意Hubs中Group的概念,客户端断开连接后,即使没有显示将其从Group中移除,也会自动离开加入的Group;
public override async Task OnConnectedAsync()
{
await Groups.AddToGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "SignalR Users");
await base.OnDisconnectedAsync(exception);
}



错误处理



Hubs中为捕获的异常将会抛到调用的客户端层,好像真的是自己本地的函数一样,所以客户端需要利用自身的异常机制来处理可能遇到的错误。



connection.invoke("SendMessage", user, message).catch(err => console.error(err));



发布于: 2020 年 06 月 11 日阅读数: 63
用户头像

还未添加个人签名 2018.05.21 加入

还未添加个人简介

评论

发布
暂无评论
SignalR Core之Hubs基本概念