Signalr не вызывает функции на стороне клиента

Я использую «Осеннее» обновление VS2012 с пакетом Signalr 1.0.0. Вызов функций на стороне сервера работает нормально. Однако клиентские функции не вызываются. Ничего не происходит, когда вызывается onBroadcastMessage() (см. ниже).

Вопросы:

  • Что мне не хватает?
  • Есть ли способ отладить вызов клиента?

Спасибо!

Код сервера:

using Microsoft.AspNet.SignalR;

namespace KPMain
{
    public class RealtimeConnectionHub : Hub
    {
        public void BroadcastMessage(string name, string message) {
            Clients.All.onBroadcastMessage(name, message);
        }
    }
}

Регистрация маршрута:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes) {
        HubConfiguration hubConfig = new HubConfiguration();
#if DEBUG
        hubConfig.EnableDetailedErrors = true;
#endif
        routes.MapHubs(hubConfig);

        ...
    }
}

Код клиента (упрощенный):

var rtcom = new RealtimeConnection();
rtcom.init({debug: true}, function () {
    rtcom.subscribe(function (sender, message) {
        if (message) {
            alert("message");
        }
    });
});

RealtimeConnection: function () {    
    var
        _rtHub = $.connection.realtimeConnectionHub,
        _initialized = false,                
        _init = function (options, cb) {
            options = options || {};

            $.connection.hub.logging = options.debug;
            $.connection.hub.start().done(function () {
                _initialized = true;

                if (cb) { cb(); }
            });
        },

        _broadcast = function (message) {
            if (_initialized) {
                _rtHub.server.broadcastMessage("testuser", message);
            }
        },

        _subscribe = function (cb) {
            if (_initialized) {
                _rtHub.client.onBroadcastMessage = cb;
            }
        };

    return {
        initialized: _initialized,
        broadcast: _broadcast,
        subscribe: _subscribe,
        init: _init
    };
}

$("#container").on("click", "button.chat-btnSendMessage", function () {
    rtcom.broadcast($(this).parent().find("input").val());
});

Журнал (используя хром):

[16:58:01 GMT+0100 (W. Europe Standard Time)] SignalR: Negotiating with '/signalr/negotiate'. jquery.signalR-1.0.0.js:54
[16:58:02 GMT+0100 (W. Europe Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://w2008r2portal/signalr/connect?transport=serverSentEvents&connectionT…EgDDEU0WLhHVzI7ZUnA0impltR7HYNTGHUJJYAXew1Leg2&connectionData=%5B%5D&tid=0' jquery.signalR-1.0.0.js:54
[16:58:03 GMT+0100 (W. Europe Standard Time)] SignalR: EventSource connected jquery.signalR-1.0.0.js:54
[16:58:03 GMT+0100 (W. Europe Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332 and a connection lost timeout of 20000 


Request URL:http://xxx/signalr/send?transport=serverSentEvents&connectionToken=lnTczBgQB0dj...
Request Method:POST
Status Code:200 OK

Request Headers
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Authorization:Negotiate YIIFXQYGKwYBBQUCoIIFUTCCBU2...
Connection:keep-alive
Content-Length:148
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Host:w2008r2portal
Origin:http://w2008r2portal
Referer:http://w2008r2portal/?tab=Start
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
X-Requested-With:XMLHttpRequest

Query String Parameters
transport:serverSentEvents
connectionToken:lnTczB...

Form Data
data:{"H":"realtimeconnectionhub","M":"BroadcastMessage","A":["testuser","test"],"I":0}

Response Headers
Cache-Control:no-cache
Content-Type:application/json; charset=UTF-8
Date:Mon, 25 Feb 2013 15:58:04 GMT
Expires:-1
Persistent-Auth:false
Pragma:no-cache
Server:Microsoft-IIS/7.5
Transfer-Encoding:chunked
WWW-Authenticate:Negotiate oYGyMIGvoAMKAQChCwY...
X-AspNet-Version:4.0.30319
X-Content-Type-Options:nosniff
X-Powered-By:ASP.NET

person mhu    schedule 25.02.2013    source источник


Ответы (1)


Таким образом, ваша проблема заключается в том, что вы начинаете свое соединение до того, как у вас есть какие-либо методы на стороне клиента, зарегистрированные с вашим прокси-сервером.

Есть два способа решить эту проблему.

  1. В вашей инициализации до $.connection.hub.start вызовите свой метод _subscribe.
  2. Перед запуском убедитесь, что у вас есть по крайней мере 1 метод на стороне клиента (требуется "подписаться" на входящие сообщения). Используйте .on для подписки на методы хаба после запуска.

Итак, вот два подхода в коде.

1:

var rtcom = new RealtimeConnection();
rtcom.init({debug: true});

RealtimeConnection: function () {    
    var
        _rtHub = $.connection.realtimeConnectionHub,
        _initialized = false,                
        _init = function (options, cb) {
            options = options || {};

            $.connection.hub.logging = options.debug;

            _rtHub.client.onBroadcastMessage = function() {
                alert("message");
            };

            $.connection.hub.start().done(function () {
                _initialized = true;

                if (cb) { cb(); }
            });
        },

        _broadcast = function (message) {
            if (_initialized) {
                _rtHub.server.broadcastMessage("testuser", message);
            }
        },

    return {
        initialized: _initialized,
        broadcast: _broadcast,
        init: _init
    };
}

$("#container").on("click", "button.chat-btnSendMessage", function () {
    rtcom.broadcast($(this).parent().find("input").val());
});

2:

var rtcom = new RealtimeConnection();
rtcom.init({debug: true}, function () {
    rtcom.subscribe(function (sender, message) {
        if (message) {
            alert("message");
        }
    });
});

RealtimeConnection: function () {    
    var
        _rtHub = $.connection.realtimeConnectionHub,
        _initialized = false,                
        _init = function (options, cb) {
            options = options || {};

            // Need to have at least 1 function registered to be subscribed to hub
            _rtHub.client.foo = function() {};

            $.connection.hub.logging = options.debug;
            $.connection.hub.start().done(function () {
                _initialized = true;

                if (cb) { cb(); }
            });
        },

        _broadcast = function (message) {
            if (_initialized) {
                _rtHub.server.broadcastMessage("testuser", message);
            }
        },

        _subscribe = function (cb) {
            if (_initialized) {
                _rtHub.on("onBroadcastMessage", cb);
            }
        };

    return {
        initialized: _initialized,
        broadcast: _broadcast,
        subscribe: _subscribe,
        init: _init
    };
}

$("#container").on("click", "button.chat-btnSendMessage", function () {
    rtcom.broadcast($(this).parent().find("input").val());
});

Надеюсь это поможет!

person N. Taylor Mullen    schedule 25.02.2013
comment
Определение клиентской функции перед вызовом start() сработало. Должен ли я был прочитать это на вики-странице Signalr? - person mhu; 25.02.2013
comment
Хорошо, этот вопрос задают довольно часто, я обновлю FAQ, чтобы учесть его. - person N. Taylor Mullen; 26.02.2013
comment
Запуск клиентского бабла после определения клиентских функций решил проблему здесь. Большое спасибо ! - person John-Philip; 30.11.2016