Подтвердить что ты не робот

Междоменный домен не будет работать с SignalR PersistentConnection

ПРИМЕЧАНИЕ. Кто-то изначально задал этот вопрос, но удалил его, прежде чем я смог опубликовать свой ответ. Поскольку этот вопрос охватывает многие проблемы, с которыми сталкиваются разработчики при попытке заставить SignalR работать в междоменном пространстве, я решил его повторить. Кроме того, я уже написал ответ!

Я запускаю сервер SignalR 1.0.1 в проекте ASP.NET MVC.NET Framework 4. У меня есть другое приложение ASP.NET в другом домене (другой локальный порт), пытающийся подключиться через клиент JavaScript. Я получаю это, когда мое приложение пытается подключиться:

XMLHttpRequest cannot load http://localhost:31865/api/negotiate?_=1363105027533.
Origin http://localhost:64296 is not allowed by Access-Control-Allow-Origin.

Я выполнил все шаги, чтобы включить поддержку междоменной поддержки с помощью SignalR - что мне не хватает?

  • jQuery.support.cors = true;
  • $.connection('http://localhost:31865/api', '', false, { jsonp: true, xdomain: true });
  • RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
  • RouteTable.Routes.MapConnection<ApiConnection>("/api", "api");

Я также добавил в проект Web.config следующее:

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Я использую PersistentConnection для моего сервера SignalR, а не концентраторы.

Любые идеи?

4b9b3361

Ответ 1

MapHubs будет настраивать конечную точку в /signalr для связи со всеми вашими классами Hub. Поскольку вы не используете концентраторы, вызов MapHubs не нужен. Вызов MapHubs также не влияет на конфигурацию вашего/api-соединения.

Ваш вызов MapConnection должен быть изменен следующим образом:

RouteTable.Routes.MapConnection<ApiConnection>("api", "api",
    new ConnectionConfiguration { EnableCrossDomain = true });

ПРИМЕЧАНИЕ. Второй аргумент MapConnection - это URL. Первым аргументом является имя маршрута. / не требуется, но в любом случае это не повредит.

  • Настройка jQuery.support.cors = true; должна выполняться ТОЛЬКО "Чтобы разрешить междоменные запросы в средах, которые еще не поддерживают корсеты, но разрешают междоменные запросы XHR (гаджет Windows и т.д.)," [1]. Это не относится ни к каким версиям IE или к любому другому браузеру, о котором я знаю. Если браузер не поддерживает CORS, SignalR уже автоматически вернется к JSONP , если не установит jQuery.support.cors в значение true.

    Если вы просто установите значение true вслепую, SignalR будет считать, что среда поддерживает междоменные запросы XHR, а не автоматически возвращается к рендерингу JSONP. SignalR не может установить междоменные подключения во время работы в браузерах, которые действительно не поддерживают CORS.

  • $.connection('http://localhost:31865/api', '', false, { jsonp: true, xdomain: true }); неверно. Вам нужно только

    var connection = $.connection('http://localhost:31865/api');
    

    xdomain больше не является вариантом для клиента SignalR JS, и если вы действительно хотите указать jsonp, вы должны сделать это, когда вы start подключаетесь так:

     connection.start({ jsonp: true}).done(function () { /* ... */ });
    

    Я должен повторить, что SignalR автоматически вернется к JSONP, если среда не поддерживает CORS, поэтому вы не должны указывать этот параметр самостоятельно. JSONP не требует заголовка Access-Control-Allow-Origin, но он заставляет SignalR использовать самый неэффективный транспорт: длительный опрос.

  • Вам не нужно устанавливать customHeaders в свой Web.config. SignalR автоматически установит заголовок Access-Control-Allow-Origin в ответах SignalR, когда вы установите EnableCrossDomain в true в ConnectionConfiguration.

Ссылка https://github.com/SignalR/SignalR/wiki/QuickStart-Persistent-Connections для получения дополнительных рекомендаций, используя PersistentConnections.