无法使用 SignalR 读取未定义的属性“客户端”

vid*_*uch 5 signalr asp.net-web-api signalr-hub

我一整天都在为此工作,但没有运气。我也尝试过(几乎)每一个 SO 问题,但我没有让它起作用......

我正在使用非常简单的 SignalR 推送消息和单独的简单前端运行 web api 来显示此推送消息。在我的情况下,推送消息是不断变化的数字。

索引.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>test app</title>

    <script src="scripts/jquery-2.1.4.js"></script>
    <script src="scripts/jquery.signalR-2.2.0.js"></script>

    <script src="/signalr/hubs"></script>
</head>
<body>
    <div id="testElm">TEST: </div>

    <script type="text/javascript">
        $(document).ready(function () {

            $.connection.hub.url = "http://localhost:55833/signalr";
            var hub = $.connection.displayHub;

            hub.client.pushMessage = function (response) {

                $('#testElm').text(response);
            };

            $.connection.hub.start();
        });
    </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我的枢纽班

public class DisplayHub : Hub
{
    public DisplayHub() : this(GlobalHost.ConnectionManager.GetHubContext<DisplayHub>().Clients) { }

    public DisplayHub(IHubConnectionContext<dynamic> clients)
    {
    }

    public void PushMessage(string message)
    {
        // generate random number and send it every 1s for testing

        Clients.All.pushMessage(randomNumber);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行时

$.connection.hub.logging = true;
Run Code Online (Sandbox Code Playgroud)

这是我得到的日志

2015-06-15 16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Auto detected cross domain url.
2015-06-15 16:44:15.314 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Negotiating with 'http://localhost:55833/signalr/negotiate?clientProtocol=1.5'.
2015-06-15 16:44:15.434 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: webSockets transport starting.
2015-06-15 16:44:15.435 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Connecting to websocket endpoint 'ws://localhost:55833/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=h7UAGOrF6RP8JUE%2F82K84E8NSZOd8jsuijsCQ2Jyh1jRi7zXmIpoVnIP9tjEjlcWvxihtZBNt6BYdaAW2jp574B5nXS%2BJFEW%2F%2BdixsiV0yu3YwaN5ERh6yhYtkvztQSQ&tid=5'.
2015-06-15 16:44:15.451 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Websocket opened.
2015-06-15 16:44:15.510 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: webSockets transport connected. Initiating start request.
2015-06-15 16:44:15.518 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: The start request succeeded. Transitioning to the connected state.
2015-06-15 16:44:15.518 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
Run Code Online (Sandbox Code Playgroud)

我不断得到

Cannot read property 'client' of undefined
Run Code Online (Sandbox Code Playgroud)
  • 检查“集线器”将显示集线器未定义......
  • 浏览到http://localhost:55833/signalr/hubs我可以看到正在创建的服务器上的集线器。
  • 暂时合并 API 和前端,一切都会正常工作,但如果我将它们分开,我会得到上述错误...
  • 使用 [HubName("displayHub")] 属性没有区别。
  • 根据上面的日志正确设置了 CORS

任何想法是什么导致错误?有没有办法可以进一步调试 signalR 以了解发生了什么?

更新 1:

在阅读了http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client上的 ASP.NET SignalR Hubs API Guide - JavaScript 后, 我已按照以下要求更改了代码没有生成的代理段落:

var conn = $.hubConnection("http://localhost:55833/signalr");
var hubProxy = conn.createHubProxy('displayHub');

hubProxy.on('pushMessage', function (response) {
    $('#testElm').text(response);
});

conn.start();
Run Code Online (Sandbox Code Playgroud)

它开始起作用了……有人能解释一下为什么吗?

Was*_*asp 5

根据您的问题,我了解到您有 2 个不同的客户端和服务器应用程序,并且您正在使用 CORS。您第一次尝试失败的原因是您没有将动态 SignalR 端点设置为面向服务器应用程序。你应该改变这个:

<script src="/signalr/hubs"></script>
Run Code Online (Sandbox Code Playgroud)

进入这个:

<script src="http://localhost:55833/signalr/hubs"></script>
Run Code Online (Sandbox Code Playgroud)

原因是,该端点动态生成表示集线器形状的 Javascript 代码,因此需要在集线器所在的应用程序(即服务器)上调用它。