Поделиться через


Устранение неполадок SignalR (SignalR 1.x)

Патрик Флетчер

Предупреждение

Эта документация не для последней версии SignalR. Взгляните на ASP.NET Core SignalR.

В этом документе описаны распространенные проблемы, связанные с SignalR.

Этот документ содержит следующие разделы.

Вызов методов между клиентом и сервером автоматически завершается сбоем

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

Чтобы дополнительно исследовать методы клиента, которые не вызываются, можно включить ведение журнала перед вызовом метода start в концентраторе, чтобы узнать, какие вызовы поступают с сервера. Сведения о включении ведения журнала в приложении JavaScript см. в статье Включение ведения журнала на стороне клиента (версия клиента JavaScript). Сведения о включении ведения журнала в клиентском приложении .NET см. в статье Включение ведения журнала на стороне клиента (версия клиента .NET).

Метод с ошибкой, неправильная сигнатура метода или неправильное имя концентратора

Если имя или сигнатура вызываемого метода не полностью соответствуют соответствующему методу на клиенте, вызов завершится ошибкой. Убедитесь, что имя метода, вызываемого сервером, совпадает с именем метода на клиенте. Кроме того, SignalR создает прокси-сервер концентратора с помощью методов с верблюдами, как это уместно в JavaScript, поэтому метод, вызываемый SendMessage на сервере, будет вызываться sendMessage в прокси-сервере клиента. Если вы используете атрибут в коде HubName на стороне сервера, убедитесь, что имя, используемое для создания концентратора на клиенте, совпадает с именем. Если вы не используете HubName атрибут , убедитесь, что имя концентратора в клиенте JavaScript имеет верблюдий регистр, например chatHub вместо ChatHub.

Повторяющееся имя метода на клиенте

Убедитесь, что на клиенте нет повторяющегося метода, который отличается только по регистру. Если в клиентском приложении есть метод с именем sendMessage, убедитесь, что также нет метода с именем SendMessage .

Отсутствует средство синтаксического анализа JSON на клиенте

SignalR требует наличия средства синтаксического анализа JSON для сериализации вызовов между сервером и клиентом. Если в клиенте нет встроенного средства синтаксического анализа JSON (например, Интернет-Обозреватель 7), необходимо включить его в приложение. Средство синтаксического анализа JSON можно скачать здесь.

Сочетание синтаксиса Hub и PersistentConnection

SignalR использует две модели связи: Hubs и PersistentConnections. Синтаксис вызова этих двух моделей связи в клиентском коде отличается. Если вы добавили концентратор в код сервера, убедитесь, что во всем клиентском коде используется правильный синтаксис концентратора.

Код клиента JavaScript, создающий PersistentConnection в клиенте JavaScript

var myConnection = $.connection('/echo');

Код клиента JavaScript, создающий прокси-сервер концентратора в клиенте JavaScript

var myHub = $.connection.MyHub;

Код сервера C#, который сопоставляет маршрут с PersistentConnection

RouteTable.Routes.MapConnection<MyConnection>("my", "/echo");

Код сервера C#, который сопоставляет маршрут с концентратором или с несколькими концентраторами при наличии нескольких приложений

RouteTable.Routes.MapHubs();

Подключение началось до добавления подписок

Если подключение концентратора запускается до того, как методы, которые могут быть вызваны с сервера, добавляются на прокси-сервер, сообщения не будут получены. Следующий код JavaScript не запустит центр должным образом:

Неправильный код клиента JavaScript, который не позволяет получать сообщения Центров

var chat = $.connection.chatHub;
$.connection.hub.start().done(function () {
    chat.client.broadcastMessage = function (name, message) {...};
});

Вместо этого добавьте подписки на метод перед вызовом Start:

Клиентский код JavaScript, который правильно добавляет подписки в концентратор

var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {...};
    $.connection.hub.start().done(function () {
        ...
    });

Отсутствует имя метода на прокси-сервере концентратора

Убедитесь, что метод, определенный на сервере, подписан на клиенте. Несмотря на то, что сервер определяет метод, он все равно должен быть добавлен в прокси-сервер клиента. Методы можно добавить в прокси-сервер клиента следующими способами (обратите внимание, что метод добавляется client в член концентратора, а не в центр напрямую):

Клиентский код JavaScript, добавляющий методы к прокси-серверу концентратора

// Method added to proxy in JavaScript:
myHubProxy.server.method1 = function (param1, param2) {...};
//Multiple methods added to proxy in JavaScript using jQuery:
$.extend(myHubProxy.server, {
    method1: function (param1, param2) {...},
    method2: function (param3, param4) {...}
});

Методы концентратора или концентратора не объявлены как общедоступные

Чтобы быть видимыми на клиенте, реализация и методы концентратора должны быть объявлены как public.

Доступ к центру из другого приложения

Доступ к Центрам SignalR можно получить только через приложения, реализующие клиенты SignalR. SignalR не может взаимодействовать с другими библиотеками обмена данными (например, с веб-службами SOAP или WCF). Если для целевой платформы нет клиента SignalR, вы не сможете напрямую получить доступ к конечной точке сервера.

Сериализация данных вручную

SignalR будет автоматически использовать JSON для сериализации параметров метода. Вам не нужно делать это самостоятельно.

Метод удаленного концентратора не выполняется на клиенте в функции OnDisconnected

В этом весь замысел. При OnDisconnected вызове концентратор уже вошел в Disconnected состояние , что не позволяет вызывать другие методы концентратора.

Код сервера C#, который правильно выполняет код в событии OnDisconnected

public class MyHub : Hub
{
    public override Task OnDisconnected()
    {
        // Do what you want here
        return base.OnDisconnected();
    }
}

Достигнуто ограничение на подключение

При использовании полной версии IIS в клиентской операционной системе, такой как Windows 7, накладывается ограничение на 10 подключений. При использовании клиентской ОС используйте IIS Express, чтобы избежать этого ограничения.

Междоменные подключения настроены неправильно

Если междоменовое подключение (для которого URL-адрес SignalR находится не в том же домене, что и страница размещения), настроено неправильно, подключение может завершиться ошибкой без сообщения об ошибке. Сведения о том, как включить междоменный обмен данными, см. в статье Установка междоменного подключения.

Подключение с использованием NTLM (Active Directory) не работает в клиенте .NET

Подключение в клиентском приложении .NET, использующее безопасность домена, может завершиться ошибкой, если подключение настроено неправильно. Чтобы использовать SignalR в среде домена, задайте необходимое свойство подключения следующим образом:

Код клиента C#, реализующий учетные данные подключения

connection.Credentials = CredentialCache.DefaultCredentials;

Другие проблемы с подключением

В этом разделе описываются причины и решения для определенных симптомов или сообщений об ошибках, возникающих во время подключения.

Ошибка Start must be called before data can be sent (Запуск должен быть вызван до отправки данных)

Эта ошибка обычно возникает, если код ссылается на объекты SignalR до начала подключения. Подключение обработчиков и подобных методов, которые будут вызывать методы, определенные на сервере, должны быть добавлены после завершения подключения. Обратите внимание, что вызов Start является асинхронным, поэтому код после вызова может быть выполнен до его завершения. Лучший способ добавить обработчики после полного запуска соединения — поместить их в функцию обратного вызова, которая передается в качестве параметра в метод start:

Клиентский код JavaScript, который правильно добавляет обработчики событий, ссылающиеся на объекты SignalR

$.connection.hub.start().done(function () {
    // Wire up Send button to call NewContosoChatMessage on the server.
    $('#newContosoChatMessage').click(function () {
        contosoChatHubProxy.server.newContosoChatMessage(
            $('#displayname').val(), $('#message').val());
            $('#message').val('').focus();
    });

Эта ошибка также будет отображаться, если соединение останавливается, пока на объекты SignalR по-прежнему ссылаются.

Ошибка "301 Перемещено навсегда" или "302 Временно перемещено"

Эта ошибка может возникнуть, если проект содержит папку с именем SignalR, которая будет мешать работе автоматически созданного прокси-сервера. Чтобы избежать этой ошибки, не используйте папку с именем SignalR в приложении или отключите автоматическое создание прокси-сервера. Дополнительные сведения см. в статье Созданный прокси-сервер и его действия.

Ошибка "403 Запрещено" в клиенте .NET или Silverlight

Эта ошибка может возникать в междоменных средах, где междоменная связь не включена должным образом. Сведения о том, как включить междоменный обмен данными, см. в статье Установка междоменного подключения. Сведения о том, как установить междоменные подключения в клиенте Silverlight, см. в статье Междоменные подключения от клиентов Silverlight.

Ошибка "404 Не найдено"

Существует несколько причин этой проблемы. Проверьте все перечисленные ниже действия.

  • Ссылка на адрес прокси-сервера концентратора неправильно отформатирована: Эта ошибка обычно возникает, если ссылка на созданный адрес прокси-сервера концентратора отформатирована неправильно. Убедитесь, что ссылка на адрес концентратора сделана правильно. Дополнительные сведения см. в статье Ссылка на динамически создаваемый прокси-сервер .
  • Добавление маршрутов в приложение перед добавлением маршрута концентратора: Если приложение использует другие маршруты, убедитесь, что первым добавленным маршрутом является вызов MapHubs.

"Внутренняя ошибка сервера 500"

Это очень общая ошибка, которая может иметь самые разные причины. Сведения об ошибке должны отображаться в журнале событий сервера, или их можно найти с помощью отладки сервера. Более подробные сведения об ошибках можно получить, включив подробные ошибки на сервере. Дополнительные сведения см. в разделе Обработка ошибок в классе Hub.

Ошибка TypeError: <hubType> is undefined

Эта ошибка возникает, если вызов MapHubs не выполнен должным образом. Дополнительные сведения см. в статье Регистрация маршрута SignalR и настройка параметров SignalR .

JsonSerializationException не был обработанным пользовательским кодом

Убедитесь, что параметры, отправляемые в методы, не включают несериализируемые типы (например, дескрипторы файлов или подключения к базе данных). Если необходимо использовать элементы в объекте на стороне сервера, который не требуется отправлять клиенту (в целях безопасности или сериализации), используйте JSONIgnore атрибут .

Ошибка "Ошибка протокола: неизвестный транспорт"

Эта ошибка может возникнуть, если клиент не поддерживает транспорты, которые использует SignalR. Сведения о том, какие браузеры можно использовать с SignalR, см. в разделе Транспорты и резервные варианты .

"Создание прокси-сервера Центра JavaScript отключено".

Эта ошибка возникает, если DisableJavaScriptProxies задан параметр , а также включает ссылку на динамически создаваемый прокси-сервер в signalr/hubs. Дополнительные сведения о создании прокси-сервера вручную см. в разделе Созданный прокси-сервер и его действия.

Ошибка "Идентификатор подключения имеет неправильный формат" или "Удостоверение пользователя не может измениться во время активного подключения SignalR"

Эта ошибка может возникать, если используется проверка подлинности и клиент выходит из системы до остановки подключения. Решение заключается в остановке подключения SignalR перед выходом клиента из системы.

"Не перехваченная ошибка: SignalR: jQuery не найден. Убедитесь, что ссылка на jQuery указана до ошибки SignalR.js файла"

Для запуска клиента JavaScript SignalR требуется jQuery. Убедитесь, что ссылка на jQuery верна, что используемый путь является допустимым и что ссылка на jQuery находится перед ссылкой на SignalR.

Ошибка "Uncaught TypeError: Не удается прочитать свойство "<property>" из undefined

Эта ошибка возникает из-за неправильной ссылки на jQuery или прокси-сервер концентраторов. Убедитесь, что ссылка на jQuery и прокси-сервер концентраторов верна, что используемый путь является допустимым и что ссылка на jQuery находится перед ссылкой на прокси-сервер концентраторов. Ссылка по умолчанию на прокси-сервер концентраторов должна выглядеть следующим образом:

Html-код на стороне клиента, который правильно ссылается на прокси-сервер Центров

<script src="/signalr/hubs"></script>

Ошибка "RuntimeBinderException была необработана кодом пользователя"

Эта ошибка может возникнуть, если используется неправильная перегрузка Hub.On . Если метод имеет возвращаемое значение, тип возвращаемого значения должен быть указан в качестве параметра универсального типа:

Метод, определенный на клиенте (без созданного прокси-сервера)

MyHub.On<ReturnType>("MethodName", LocalMethod);

Идентификатор подключения несогласован или разрывы соединения между загрузками страниц

В этом весь замысел. Так как объект концентратора размещается в объекте страницы, концентратор удаляется при обновлении страницы. Многостраничное приложение должно поддерживать связь между пользователями и идентификаторами подключений, чтобы они были согласованными при загрузке страниц. Идентификаторы подключений могут храниться на сервере в объекте ConcurrentDictionary или базе данных.

Ошибка "Значение не может быть null"

Методы на стороне сервера с необязательными параметрами в настоящее время не поддерживаются; Если необязательный параметр опущен, метод завершится ошибкой. Дополнительные сведения см. в разделе Необязательные параметры.

Ошибка "Firefox не удается установить подключение к серверу по <адресу>" в Firebug

Это сообщение об ошибке можно увидеть в Firebug, если согласование транспорта WebSocket завершается сбоем и вместо него используется другой транспорт. В этом весь замысел.

Ошибка "Удаленный сертификат недопустим в соответствии с процедурой проверки" в клиентском приложении .NET

Если серверу требуются пользовательские сертификаты клиента, можно добавить сертификат x509 к подключению перед выполнением запроса. Добавьте сертификат в подключение с помощью Connection.AddClientCertificate.

Подключение отпадает после превышения времени ожидания проверки подлинности

В этом весь замысел. Учетные данные проверки подлинности не могут быть изменены при активном подключении; Чтобы обновить учетные данные, подключение должно быть остановлено и перезапущено.

OnConnected вызывается дважды при использовании jQuery Mobile

Функция jQuery Mobile initializePage заставляет скрипты на каждой странице выполняться повторно, создавая тем самым второе подключение. К решениям этой проблемы относятся:

  • Добавьте ссылку на jQuery Mobile перед файлом JavaScript.
  • Отключите функцию, initializePage задав параметр $.mobile.autoInitializePage = false.
  • Дождитесь завершения инициализации страницы, прежде чем начать подключение.

Сообщения задерживаются в приложениях Silverlight с помощью событий, отправленных сервером

Сообщения задерживаются при использовании событий, отправленных сервером в Silverlight. Чтобы принудительно использовать длинный опрос, при запуске подключения используйте следующую команду:

connection.Start(new LongPollingTransport());

"Отказано в разрешении" с использованием протокола Forever Frame

Это известная проблема, описанная здесь. Этот симптом можно увидеть с помощью последней библиотеки JQuery; Обходной путь — перейти на более раннюю версию приложения до JQuery 1.8.2.

Ошибки компиляции и на стороне сервера

В следующем разделе содержатся возможные решения для ошибок компилятора и среды выполнения на стороне сервера.

Ссылка на экземпляр концентратора имеет значение NULL

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

HTTPContext.Current.Session имеет значение NULL

В этом весь замысел. SignalR не поддерживает состояние сеанса ASP.NET, так как включение состояния сеанса приведет к прерыванию дуплексного обмена сообщениями.

Нет подходящего метода для переопределения

Эта ошибка может возникнуть при использовании кода из более старой документации или блогов. Убедитесь, что вы не ссылаетесь на имена методов, которые были изменены или устарели (например OnConnectedAsync, ).

HostContextExtensions.WebSocketServerUrl имеет значение NULL

В этом весь замысел. Этот элемент является устаревшим и не должен использоваться.

Ошибка "Маршрут с именем signalr.hubs уже находится в коллекции маршрутов"

Эта ошибка будет обнаружена, если MapHubs приложение вызывает дважды. Некоторые примеры приложений вызывают MapHubs непосредственно в глобальном файле приложения, другие — в классе-оболочке. Убедитесь, что приложение не выполняет обе функции.

Проблемы с Visual Studio

В этом разделе описываются проблемы, возникающие в Visual Studio.

Узел "Документы скрипта" не отображается в Обозреватель решений

Некоторые из наших учебников направляют вас к узлу "Документы скриптов" в Обозреватель решений во время отладки. Этот узел создается отладчиком JavaScript и отображается только при отладке браузерных клиентов в интернет-Обозреватель; узел не будет отображаться при использовании Chrome или Firefox. Отладчик JavaScript также не будет запускаться, если запущен другой отладчик клиента, например отладчик Silverlight.

SignalR не работает в Visual Studio 2008 или более ранней версии

В этом весь замысел. Для SignalR требуется платформа .NET Framework 4 или более поздней версии; для этого требуется, чтобы приложения SignalR разрабатывались в Visual Studio 2010 или более поздней версии.

Проблемы со службами IIS

В этом разделе содержатся проблемы со службами IIS.

Сбой веб-сайта после вызова MapHubs

Эта проблема устранена в последней версии SignalR. Убедитесь, что вы используете последнюю выпущенную версию SignalR, обновив установку с помощью NuGet.

Проблемы с Azure

Этот раздел содержит сведения о проблемах с Microsoft Azure.

Сообщения не получаются через обратную панель Azure после изменения имен разделов

Разделы, используемые внутренней панелью Azure, не предназначены для настройки пользователем.