SignalR дает "ConnectionId в неправильном формате"

У меня есть проект SignalR, который работал без проблем в моих средах разработки, но как только он был перенесен в производство, почти каждый вызов завершился с ошибкой

ConnectionId находится в неправильном формате.

Я видел несколько других элементов в StackOverflow о том же сообщении об ошибке, но ни одно из них не помогло.

Я использую SignalR 2.0.2 и SignalR Scaleout с SQL Server, эффективно балансировщик нагрузки.

Код события: 3005 Сообщение о событии: произошло необработанное исключение. Время события: 2/11/2014 9:11:27 PM Время мероприятия (UTC): 2/12/2014 3:11:27 AM Идентификатор события: cff1fd93fa6d4b83b1848078a905371c Последовательность событий: 73 Событие: 10 Код события: 0 Информация о приложении:

Application domain: /LM/W3SVC/2/ROOT-3-130366479327251392 
Trust level: Full 
Application Virtual Path: / 
Application Path: C:\inetpub\wwwroot\<remvoved>
Machine name: BSDUSHC1WW09    Process information: 
Process ID: 7088 
Process name: w3wp.exe 
Account name: <remvoved>    Exception information: 
Exception type: InvalidOperationException 
Exception message: The ConnectionId is in the incorrect format.    at

Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken) at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext контекста) в Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext контекста) в Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 окружающей среды) при Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() --- Конец трассировки стека из предыдущего места, где было выбрано исключение - на System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult крыса System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() на System.Web.HttpApplication.ExecuteStep(шаг IExecutionStep, Логическое & completedSynchronously)

Запросить информацию:     URL запроса: HTTP:///signalr/подключить транспорт = serverSentEvents & connectionToken = GZlhDBCjkD1/bL1rc4Rlq2PVKYRs0B9nN7b71cU/E6x7sCsFvR1DqM/rBnDhg + URwkYyBlGmrczV59XIn/goyt9x0xXOd8Gs3Qswo1oXqSttH2QPO548C0fbdBvvlUupzS4S0Rl + aShoQwnj + qFDpA == & connectionData = [{ "Имя": ""}]

Request path: /signalr/connect 
User host address: 10.240.14.26 
User: <remvoved>
Is authenticated: True 
Authentication Type: Negotiate 
Thread account name: <remvoved>    Thread information: 
Thread ID: 23 
Thread account name: <remvoved>
Is impersonating: False 
Stack trace:    at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext

контекст, String connectionToken) в Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext контекста) в Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext контекста) в Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 окружающей среды) при Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() --- Конец трассировки стека из предыдущего места, где было выбрано исключение - на System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult крыса System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() на System.Web.HttpApplication.ExecuteStep(шаг IExecutionStep, Логическое & completedSynchronously)

Ответ 1

Так же, как при балансировке нагрузки на веб-сайте ASP.NET, использующем Session, SignalR с масштабированием SQL Server требует, чтобы все серверы, которые обрабатывали запросы SignalR , должны делиться машинным ключом.

Нет очевидного упоминания об этом в документации для SignalR, поэтому я должен предположить, что connectionToken в приведенном выше сообщении журнала событий зашифрован с помощью машинного ключа. Когда приложение попадает на сервер 1, ему назначается connectionToken, сгенерированный с использованием этого машинного машинного ключа. Если приложение затем попадает на сервер 2 с назначенным connectionToken, машина 2 не может расшифровать токен, если у него нет соответствующего машинного ключа.

В Интернете есть множество ресурсов о том, как установить машинный ключ, поэтому я оставлю только самый простой. Нажмите на веб-сайт в IIS 8 (возможно, 7) и откройте настройки Machine Key. Нажмите Generate Keys в панели действий справа. Снимите флажок "Создать уникальный ключ для каждого приложения" в разделе Validation Key и Decryption Key.

Ответ 2

Несмотря на то, что Кевин уже ответил на вопрос (который помог мне, и я его поддержал), после настройки того же машинного ключа для каждого сервера в ферме, проблема все еще была (иногда это странно работало случайным образом, но первая попытка всегда не удалась).

Вам также необходимо убедиться, что ваше приложение работает с одинаковыми учетными данными на каждом сервере. В моем сценарии пул приложений был настроен для работы под Сетевой службой (который представляет собственные учетные данные компьютера по сети). Поскольку каждый сервер имеет свои собственные учетные данные, они не совпадают, поэтому проблема еще не решена.

Мне пришлось создать пользователя с доступом к каждому серверу фермы и сделать приложение на каждом сервере для работы с этим же пользователем. Только после этого моя проблема была решена.