2015-10-01 4 views
4

Мое приложение работает под корпоративной сетью (уродливые прокси и прочее). И это работает не очень хорошо. Я надеялся, что использование https поможет, но это не так. Вот странный образец, который я вижу в журналах:Длительный опрос SignalR отключен через 5 секунд

[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Client subscribed to hub 'modemshub'. 
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.5&connectionToken=6aktO0sramoQKhQ9DC7Cs7EbXMUou8LooQRxfup4R0oZCHpBmWBFjyLup%2F3wJLloR8GtJEiUk10YOZJBaSqN8aiGAfXRR4G9hujTFTyiJiz%2FyJ4oMlBIdxqeCc5anI6k&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'. 
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: longPolling transport starting. 
[14:13:32 GMT+0600 (N. Central Asia Standard Time)] SignalR: Opening long polling request to 'https://example.com/signalr/connect?transport=longPolling&clientProt…rlCzGHl5kVLClT5ex8&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'. 
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: Long poll complete. 
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: LongPolling connected. 
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: longPolling transport connected. Initiating start request. 
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: Opening long polling request to 'https://example.com/signalr/poll?transport=longPolling&clientProtoco…rlCzGHl5kVLClT5ex8&connectionData=%5B%7B%22name%22%3A%22modemshub%22%7D%5D'. 
[14:13:33 GMT+0600 (N. Central Asia Standard Time)] SignalR: The start request succeeded. Transitioning to the connected state. 
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Long poll complete. 
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Stopping connection. 
[14:13:38 GMT+0600 (N. Central Asia Standard Time)] SignalR: Fired ajax abort async = true. 

Таким образом, устанавливается соединение и через 5 секунд она будет прервана (в то время как ConnectionTimeout составляет 110 секунд). И этот образец повторяется снова и снова. Это просто странно.

ответ

5

фон

Согласно Asp.net:

SignalR использует транспортный API для создания транспортной связи, а транспортный API зависит от наличия физического сетевого соединения для создания транспортной связи. Транспортное соединение заканчивается, когда SignalR завершает его или когда API транспорта обнаруживает, что физическое соединение нарушено.

Физические соединения могут быть медленными или могут произойти перебои в подключении. В зависимости от таких факторов, как длина прерывания, транспортное соединение может быть отключено. SignalR затем пытается восстановить транспортное соединение. Иногда API транспортного соединения обнаруживает прерывание и отключает транспортное соединение, а SignalR сразу обнаруживает, что соединение потеряно. В других сценариях ни API транспортного соединения, ни SignalR не сразу узнают, что связь была потеряна. Для всех транспортов, за исключением длительного опроса, клиент SignalR использует функцию keepalive для проверки потери связи, которую транспортный API не может обнаружить.

Troubleshooting

Обратите внимание, что SignalR 2.1 введены Keep-alives для длительного опроса. Это может быть проблематично, если что-то мешает чересстрочным HTTP-ответам. Если вы хотите установить disablekeepalive, установите KeepAlive на номер null. Keepalive функциональность автоматически disabled для длинный опрос транспорт.

Если вы using a Self-Host, используйте следующую процедуру с 3 арг вместо:

GlobalHost.Configuration.ConnectionTimeout = new TimeSpan(0,0,110); 
GlobalHost.Configuration.DisconnectTimeout = new TimeSpan(0,0,30); 
GlobalHost.Configuration.KeepAlive = new TimeSpan(0,0,10); 

как различные альтернативы для поддержки оставление в живых «как» функция для длительного опроса, создать имя метода сервера это Ping:

public class MyHub : Hub 
{ 
    public void Ping() 
    { 
    } 
} 

Затем на клиенте создать интервал, в котором будет Ping сервер:

var proxy = $.connection.myHub, 
    intervalHandle; 
... 
$.connection.hub.disconnected(function() { 
    clearInterval(intervalHandle); 
}); 
... 
$.connection.hub.start().done(function() { 
    // Only when long polling 
    if($.connection.hub.transport.name === "longPolling") { 
     // Ping every 10s 
     intervalHandle = setInterval(function() { 
      // Ensure we're connected (don't want to be pinging in any other state). 
      if($.connection.hub.state === $.signalR.connectionState.connected) { 
       proxy.server.ping().fail(function() { 
        // Failed to ping the server, we could either try one more time to ensure we can't reach the server 
        // or we could fail right here. 
        TryAndRestartConnection(); // Your method 
       }); 
      } 
     }, 10000); 
    } 
}); 

Надеюсь быть полезным.

0

Предположим, что советы доступны в Understanding and Handling Connection Lifetime Events in SignalR, где вы можете использовать хорошие решения для управления временем жизни соединения на основе сетевой проблемы. Кроме того, в проблемах SignalR я нашел для вас следующее решение, которое также работает с длинным опросом.

Вы можете установить свойство KeepAlive в ConfigurationManager, и SignalR отправит пустой кадр данных (на основе транспорта) в указанный интервал, чтобы сохранить соединение в сети (см. Allow host to specify keep alive times). Текущий механизм тайм-аута делает потоковые протоколы разными.

Смежные вопросы