【问题标题】:Push Data To Client Using SignalR使用 SignalR 将数据推送到客户端
【发布时间】:2017-09-30 03:51:22
【问题描述】:

很抱歉可能会在此处创建重复的线程,但我根本无法按照我找到的其他示例让我的 Web 应用程序执行我需要的操作。

我的目标是做以下事情之一:

选项 1 - 理想解决方案
仅当对网页上显示的数据进行更改时,才从数据库中获取数据并更新网页上的 UI。例如,如果用户正在查看服务票证,我不想更新该页面上的 UI,除非该票证已更改。

选项 2 - 可接受的解决方案
每 x 秒从数据库中获取数据,并使用该数据更新网页上的 UI。

选项 2 的当前实现如下。它涉及每 60 秒发送一个异步 HTTP 请求以获取数据:

// start checking for new messages every 60 seconds
setInterval(function () {
    $.ajax({
        async: true,
        type: "POST",
        contentType: "application/json; charset=utf-8;",
        url: "/AJAX_Handlers/CheckForNewMessages.ashx",
        dataType: "json",
        success: function (Result) {
            var new_message_received = Result[0]["NewMessageReceived"];

            if (new_message_received) {
                $("#DIVMessageReminder").html("<strong>You have " + num_new_messages + " new message(s).</strong>");
                $("#DIVMessageReminder").show();
            }
            else {
                $("#DIVMessageReminder").hide();
            }
        }
    });
}, 60000);

我不想每 60 秒发送一次 HTTP 请求,而是希望使用 SignalR 每 60 秒将该数据推送到客户端。

作为一个简单的示例,我创建了以下 Hub,其中包含获取服务器上当前时间的方法:

Imports Microsoft.AspNet.SignalR

Public Class ServerTimeHub
    Inherits Hub

    Public Sub GetServerTime()
        Dim current_time As String = Now.ToString()
        Clients.All.updateTime(current_time)
    End Sub

End Class

还有一个基本的文本框:

<input id="TXTLongPollingTest" type="text" class="form-control" />

还有我的客户端代码:

var hub = $.connection.serverTimeHub;

hub.client.updateTime = function (new_time) {
    $("#TXTLongPollingTest").val(new_time);
}

$.connection.hub.start().done(function () {
    alert("connected to the SignalR hub");
    hub.getServerTime();
}).fail(function (err) {
    alert("failed to connect to SignalR hub: " + err);
});

起初我试图让它只获取一次服务器时间。我的代码将成功连接到集线器,但随后会引发错误,提示“未捕获的 TypeError:hub.getServerTime 不是函数”。这是我无法克服的第一个问题。

第二个问题是:如何让集线器定期(例如每 1 秒)向客户端发送当前时间?

【问题讨论】:

    标签: signalr


    【解决方案1】:

    这是我为实现类似目标所做的工作。基本上每 30 秒从数据库中获取数据并广播给客户端。

    在我的 global.asax.cs 中,我有这个以确保每当我的网站启动/重新启动时,它都会启动我的转发器:

    protected void Application_Start(object sender, EventArgs e)
    {
        GetTeamData.TeamDataRepeater();
    }
    

    在我的 GetTeamData.cs 中,我有一个设置为每 30 秒运行一次的计时器

    public class GetTeamData
      {    
        static Timer TeamDataTimer = new Timer();
    
        public static void TeamDataRepeater()
        {
              TeamDataTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent_TeamDataBroadcaster);
              TeamDataTimer.Interval = 30000; //30 Seconds
              TeamDataTimer.Start(); 
        }
    
        public static void OnTimedEvent_TeamDataBroadcaster(Object sender, ElapsedEventArgs e)
        {
              updateFirstRow(); 
        }
    
        public static void updateFirstRow()
        {
              IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MsgHub>();
              hubContext.Clients.All.pushMyData(mydata1, mydata2, mydata3);
        }           
    
       }
    

    我的客户端 java 脚本有:

    //I have already started my connection
    
    $(function () {
        var chat = $.connection.msgHub;
        chat.client.pushMyData = function (mydata1, mydata2, mydata3)
        {
        //Do something with the returned data now
        }
    });
    

    请注意,我已经删除了一些内容,例如使用 try/catch 只是为了给你一个例子。

    希望对您有所帮助。

    【讨论】:

    • 尽管这似乎与所有其他示例非常相似,但这对我有用。非常感谢你的帮助!我仍然想知道是否有人只有在相关数据发生更改时才获取新数据的解决方案。
    猜你喜欢
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多