专栏首页NetCoreAsp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参

Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参

继续学习

最近一直在使用Asp.Net Core SignalR(下面成SignalR Core)为小程序提供websocket支持,前端时间也发了一个学习笔记,在使用过程中稍微看了下它的源码,不得不说微软现在真的强大,很多事情都帮你考虑到了,比如使用Redis,使用Redis后,你的websocket就支持横向扩展了,使用的方式也特别简单,只需要在services.AddSignalR的后面再加上:

.AddRedis(options =>
{
    options.Configuration.ConnectTimeout = 30;
    options.Configuration.EndPoints.Add("redis ip");
})

SignalR Core利用了Redis的发布订阅功能,就实现了横向扩展,再也不用担心一台ws服务器不够用了.

今天要说的并不是SignalR Core的负载均衡方式,而是如何优雅的调用前端方法。大家都知道SignalR Core除了可以建立websocket连接,还能双向调用,服务器调用客户端方法,客户端也能调用服务器的方法。

原始调用

我们看下如何调用客户端方法:

public class ChatHub : Hub
{
    //服务端方法
    public async Task SendMessage(string user, string message)
    {
        //ReceiveMessage 为客户端方法,让所有客户端调用这个方法
        await Clients.All.SendAsync("sayHello", user, message);
    }
}

还是ChatHub~~~~~

我们可以看到在这里我们调用了客户端的sayHello,并传递了两个字符串参数user,message,是不是觉得丑陋,说实在的真心看不下去哈。而且不变维护,相当于你要把方法名硬编码,传递多少个参数也没有个准,没有好的文档后期很难维护。好在微软已经为我们考虑到了这个情况,我们可以把客户端的方法用接口的方法定义了!!!对!没错,用接口的方式定义客户端的方法!!

优雅调用

使用的方式也超级简单,我们先定义一个客户端的接口:

public interface IMyClient
{
    Task SayHello(string user, string message);
}

然后我们的Hub集成Hub,T就是你定义的客户端接口,这里也就是IMyClient,我用上面的ChatHub举例:

public class SendMessageHub : Hub<IMyClient>
{
    public async Task SendMessage(string user, string message)
    {
        await this.Clients.All.SayHello(user, "from server:" + message);
        //ReceiveMessage 为客户端方法,让所有客户端调用这个方法
        //await Clients.All.SendAsync("sayHello", user, message);
    }
}

注释掉的是我之前的方式,SayHello是客户端的方法,会通过websocket传递到前端,下图为我用小程序通讯产生的结果:

是不是SoEasy??我觉得还不算完,我们参数目前是按照数组的方式传递的,如果有限定的参数名就完美了,我们改造下IMyClient:

public interface IMyClient
{
    Task SayHello(HelloMessage message);
}

public class HelloMessage
{
    public string User { get; set; }
    public string Message { get; set; }
}

修改下我们的Hub的SendMessage方法:

public  Task SendMessage(string user, string message)
{
    return this.Clients.All.SayHello(new HelloMessage()
    {
        User = user,
        Message = "from server:" + message
    });

    //return this.Clients.All.SendAsync("sayHello", $"from server:{message}");
}

在运行下我们的小程序:

LooK,方法名没有改变,但是我们返回的参数成了一个对象,如果看过我之前那篇博文的话,应该记得在前端的时候,我需要做一个映射,来调用前端的方法,在映射中,我参数使用的是数组进行传递的,现在不需要去看数组中第几个参数是我需要使用的了,你完全可以使用:

callMethods(methods, args) {
    console.log(methods, args);
    let self = this;
    let arg = args[0];
    switch (methods) {
        case 'SayHello':
            self.sayHello(arg.message);
            break;
    }
},

这里还有个问题,就是接口中的方法名是大写开头的,而js的规范呢一般都是小写开头的,所以在映射方法的时候需要注意下,反正这个大小写问题有点不是很爽,参数在传递的时候倒是直接转换成首字母小写,我相信SignalR Core是可以实现的,只是我不知道而已,稍后在研究研究,如果可行,我会更新此篇博文。如果你要在接口中用小写来定义这个方法,也没有问题,但我觉得就是不符合规范,习惯不允许我如此粗糙,哈哈。

写在最后

至于调用的原理,我没有细看,正好在看源码的时候,看到了Hub,很疑惑,尝试了下后才发觉SignalR的牛逼,后来发现其实在SignalR 2.1中引用了这个概念,估计很多人已经在用了,但好像提到的人很少,包括微软的文档,这次也是意外发现,赶快记录下来,希望对您有用。

Asp.Net Core SignalR确实很强大,有兴趣的可以去gayhub上去研究下他们的源码。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 保护连接字符串

    保护连接字符串 摘自MSDN 保护对数据源的访问是安全应用程序最重要的目标之一。为了帮助限制对数据源的访问,必须保护连接信息(例如用户标识、密码和数据源名称)的...

    脑洞的蜂蜜
  • 复杂而艰辛的重构之路--起步

    你有没有试过,当你踏入一个新的公司,看到了几千几万几十万代码的时候,那种崩溃的感觉? 代码多不可怕,怕的是代码的可读性、维护性、扩展性是如此之差,这时候该怎么办...

    脑洞的蜂蜜
  • SSA-一种适合中小型企业的新型服务架构

    脑洞的蜂蜜
  • R聚类算法-层次聚类算法

    层次聚类(Hierarchical Clustering算法) 层次聚类算法又称为树聚类算法,它根据数据之间的距离,透过一种层次架构方式,反复将数据进行聚合,创...

    Erin
  • 超媒体:将客户端服务端分离进行到底

    2017 年年末,就职小米的一位前同事送了我一枚 F 码,我用它抢购到一枚小爱音箱。我满怀期待地装上“小爱同学”,希望能够通过她用语音控制所有小米产品。但我失望...

    用户1682855
  • 这位同学,学不会JS不是因为你笨

    不管学什么,这种学习的动力,要么是欲望,要么是痛苦。今天有一个同学问我,学习JS半个多月,依然是不会写JS,怎么办?我回答ta说,这多正常啊,如果那么容易就学会...

    web前端教室
  • 关注「腾讯云助手」公众号,接收重要通知

    公众号现已支持通知主要包括:工单、备案、余额预警、安全事件、域名相关、监控告警相关通知,其他通知正在陆续上线中。

    腾讯云助手团队
  • 小朋友学经典算法(12):分割字符串

    在分割字符串之前,先来了解一些跟字符串相关的变量或函数: (1)size_type:size_type由string类类型和vector类类型定义的类型,用以保...

    海天一树
  • 你所不知道的Python | 字符串连接的秘密

    字符串连接,就是将2个或以上的字符串合并成一个,看上去连接字符串是一个非常基础的小问题,但是在Python中,我们可以用多种方式实现字符串的连接,稍有不慎就有可...

    simpleapples
  • OpenShift Prometheus(Operator)对接应用监控数据实践

    最近在实施一个项目,将客户从原有的数人云 mesos+marathon 迁移至 Openshift,迁移的主要原因有两个,一是现有mesos+marathon平...

    泽阳

扫码关注云+社区

领取腾讯云代金券