ASP.NET MVC 4中,使用SignalR时服务器到客户端的消息无法传递

4

我创建了一个简单的测试应用来重现我在主要应用程序中遇到的问题。

我有以下的 hub 类:

[HubName("testHub")]
public class TestHub : Hub
{
    public TestHub()
    {
        System.Diagnostics.Debug.WriteLine("TestHub instantiated");
    }

    public void RunMe()
    {
        System.Diagnostics.Debug.WriteLine("Client Started");
    }

    public static void Notify(string msg)
    {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
        hubContext.Clients.All.notify("Hello!");
    }
}

我的测试网页是:

<form action="javascript: void(0)" method="post">
    <input type="button" value="Do It!" onclick="hitHub()"/>
</form>

<div id="error"></div>
<script type="text/javascript">
    var tHub;    
    $(document).ready(function () {
        tHub = $.connection.testHub;
        tHub.notify = function (msg) {
            alert(msg);
        }
        $.connection.hub.start().done(function () {
            tHub.server.runMe();
        });
    });

    function hitHub() {
        $.ajax({
            type: "POST",
            url: "@Url.Content("~/Hub/Test")" ,
            success: function (data, textStatus, jqXHR) {
            },
            error: function (data, textStatus, jqXHR) {
                $("#error")[0].innerHTML = data.responseText;
                alert("Error notifying hub.");
            }
        });

    }
</script>

最后,我的HubController:

public class HubController : Controller
{
    [AcceptVerbs(HttpVerbs.Post)]
    public void Test()
    {
        TestHub.Notify("Got it!");
    }
}

在我的Application_Start方法中,我调用RouteTable.Routes.MapHubs();
该hub会被实例化。然后调用runMe()方法传递给服务器。这一切都很正常。
问题出在我点击"Do It!"按钮时。hitHub()被调用,但是我的HubController.Test()方法被调用却没有任何错误,但客户端上什么都没有发生。
我错过了什么?
更新1:根据JcFx的答案,更改了上面的javascript代码,以便在调用$.connection.hub.start()之前设置tHub.notify。然而问题仍然存在。
更新2: Fiddler看到的是什么: What the Fiddler sees 更新3:当我跟踪MessageBus.Publish()调用时,我注意到Topic没有订阅,所以该Topic从未被调度。不确定应该在什么地方检查订阅是否完成...

另一个想法:尝试调用 GlobalHost.ConnectionManager.GetHubContext,然后从非静态函数中调用你的 notify 客户端代码。我不确定在静态方法中是否存在 hubcontext,或者是否是相同的上下文。 - Jude Fisher
尝试过了,也不行。感谢提供的想法… - Pete
第一个问题(函数的顺序)绝对是你需要修复的。不确定还有什么其他问题 - 我有几乎相同的代码,它可以正常工作。很抱歉没有帮到你... - Jude Fisher
1个回答

3

您使用了错误的语法:

var tHub;    
$(document).ready(function () {
    tHub = $.connection.testHub;
    tHub.client.notify = function (msg) {
        alert(msg);
    }
    $.connection.hub.start().done(function () {
        tHub.server.runMe();
    });
});

注意在hub上注册回调的.client属性。

谢谢,David。我希望你能发表你的看法并提供答案,当然,你做到了。我认为这是最近相对较新的更改,因为大多数网站上的示例都不使用该语法。无论如何,非常感谢。 - Pete
没错,如果有疑问,请查看文档。它们都是最新的。此外,在这里阅读:http://weblogs.asp.net/davidfowler/archive/2012/11/11/microsoft-asp-net-signalr.aspx。 - davidfowl
你不会相信我在文档中忽略了多少次这一部分。谢谢David! - Dan F
那么如何仅向特定用户发送消息呢?我尝试过 hubContext.Clients.User(userName).notify(msg); 但是这并没有起作用。 - imdadhusen
1
@imdadhusen hubContext.Clients.User(userName).notify(msg); 这个是可以工作的,但请首先查看这篇文章 点击 - Daniel Petrovaliev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接