[.NET][SignalR] 由 Server 调用 JavaScript–使用 SignalR 实践 Push 消息模式

Posted petewell

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[.NET][SignalR] 由 Server 调用 JavaScript–使用 SignalR 实践 Push 消息模式相关的知识,希望对你有一定的参考价值。

在前一个范例中,我们己经实践出来一个简单的应用程序,而这次我们要来展示 SignalR 的另一个功能:由伺服端调用用户端的 javascript 命令码的功能,而这个功能的要求必须是要实践成 Hub 的模式,因此我们可以顺便看到如何实践 Hub 类型的 SignalR 应用程序。


在前一个范例中,我们己经实践出来一个简单的应用程序,而这次我们要来展示 SignalR 的另一个功能:由伺服端调用用户端的 JavaScript 命令码的功能,而这个功能的要求必须是要实践成 Hub 的模式,因此我们可以顺便看到如何实践 Hub 类型的 SignalR 应用程序。

一样的,我们在项目内加入一个新的类 PushNotification,并且设定继承 Hub 类 (这是 Hub 应用程序的要求) 以及实践 IConnected, IDisconnect 两个界面:


using System.Threading;
using System.Threading.Tasks;
using SignalR;
using SignalR.Hubs;
using SignalR.Infrastructure;
using SignalR.Hosting.AspNet;

namespace ServerPushMessageApplication

    [HubName("push")]
    public class PushNotification : Hub, IConnected, IDisconnect
    
         // ...
    

接着,加入连线保留的对象以及实践 IConnected/IDisconnect 方法:


private static List _connectionIds = new List();
private static Task pushTask = null;
                        
public Task Disconnect()

    if (_connectionIds.Contains(this.Context.ConnectionId))
        _connectionIds.Remove(this.Context.ConnectionId);

    return null;


public Task Connect()

    _connectionIds.Add(this.Context.ConnectionId);

    return null;


public Task Reconnect(IEnumerable groups)

    return null;


这段程序的用意是,在连线进到 Hub 时,将连线代码加到连线用户的集合中,等会就会使用到,因为我们会依照用户端的 ID 来调用用户端命令码。

接着,我们加入真正重要的程序,也就是 Push 用的程序:


public PushNotification()

    pushTask = new Task(() =>
        
            while (true)
            
                if (_connectionIds.Count > 0)
                
                    foreach (string id in _connectionIds)
                        Clients[id].updateDateTime(DateTime.Now.ToString());
                

                Thread.Sleep(10000);
            
        );

    pushTask.Start();


~PushNotification()

    pushTask = null;

这段程序的用意是,会在每十秒钟时调用用户端的 updateDateTime() 命令码,并且将参数返回用户端,参数的排列与伺服端传入的顺序相同,等一下我们会实践到用户端的 JavaScript,届时就可以比较一下。

接着,我们在 Global.asax 的程序中,加入启用 Hub 的程序:


public class MvcApplication : System.Web.HttpApplication

    protected void Application_Start()
    
        AreaRegistration.RegisterAllAreas();

        // enable Hub
        RouteTable.Routes.MapHubs();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    

至此,服务器端就写好了,看起来不难吧。

接着,在项目中加入新的 View,然后加入下列的 html/JavaScript:





    
    Index
    
    
    
    


    
    

用户端部分和 Persistent Connection 的不同,就是在用户端必须要加入 “/singler/hubs” 这个命令码来源,它会产生 hub 的 metadata,如果没有它的话,用户端针对 hub 的命令码 ($.connection.push) 会失效。

其中比较重要的是 push.updateDateTime 的实践,它就是要负责接收来自伺服端的数据并在用户端做处理的,但它必须要挂在 hub 对象之下,否则没办法被调用,这也是为什么 SignalR 能做伺服端调用用户端的原因。

完成后,执行结果如下:

技术图片

可以参考用户端程序,可发现用户端只有启动连线而己,并没有主动调用服务器端,但服务器端却可以返回数据到用户端,这就是 SignalR 的神奇之处 (等以后我们讨论到细节时,你就不会觉得它神奇了 :) )。

Reference: https://github.com/SignalR/SignalR/wiki/QuickStart-Hubs

原文:大专栏  [.NET][SignalR] 由 Server 调用 JavaScript–使用 SignalR 实践 Push 消息模式


以上是关于[.NET][SignalR] 由 Server 调用 JavaScript–使用 SignalR 实践 Push 消息模式的主要内容,如果未能解决你的问题,请参考以下文章

SignalR 授权无法在带有 Identity Server 的 asp.net core angular SPA 中开箱即用

.net core 3.0 Signalr - 07 业务实现-服务端 自定义管理组用户连接

SignalR全套系列之在.Net6中实SignalR通信

使用 sql server 作为 backlplane 时 SignalR 不起作用

.NETCOREASP.NET Core SignalR

SignalR全套系列之在.Net Core 中实现长轮询