Я размещаю SignalR Hub на Windows Server 2012 с IIS в качестве веб-приложения ASP.NET, которое я успешно протестировал на своем локальном компьютере.Но когда я публикую и пытаюсь подключиться из приложения Angular, сервер отвечает 403 Forbidden на запрос /gotiate.Приложение Angular расположено в другом домене, чем сервер-концентратор.
Я читал, что это вызвано проблемой CORS, но я пробовал каждое найденное решение без каких-либо изменений.Это может быть проблема с сервером IIS или я что-то пропустил в своем коде?
Вызываемый маршрут: https://example.com/signalr/negotiate
Сервер SignalR:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true,
EnableDetailedErrors = true
};
map.RunSignalR(hubConfiguration);
});
}
}
// Hub that handles Online user list
public class OnlineHub : Hub
{
private static List<AppUserDto> _usersOnline = new List<AppUserDto>();
public OnlineHub()
{
// Automapper Setup
MappingConfig.Init();
}
public override Task OnConnected()
{
var user = GetUser();
_usersOnline.Add(user);
Clients.All.listUpdated(_usersOnline);
return base.OnConnected();
}
public override Task OnReconnected()
{
var user = GetUser();
// Add user to list of online users if it doesn't exist
if (!_usersOnline.Any(u => u.Email == user.Email))
{
_usersOnline.Add(user);
Clients.All.listUpdated(_usersOnline);
}
return base.OnReconnected();
}
public override Task OnDisconnected(bool stopCalled)
{
var user = GetUser();
if (!_usersOnline.Any(u => u.Email == user.Email))
{
// Remove user from list of online users
_usersOnline.Remove(user);
Clients.All.listUpdated(_usersOnline);
}
return base.OnDisconnected(stopCalled);
}
private AppUserDto GetUser()
{
using (var db = new EntityDbContext())
{
// Get connected AppUserDto
var user = db.AppUsers.FirstOrDefault(u => u.UserName == Context.User.Identity.Name);
// Add user to list of online users
if (user != null)
{
return Mapper.Map<AppUserDto>(user);
}
return null;
}
}
}
Служба Angular Application SignalR
import { AppSettings } from './../app.settings';
import { EventEmitter, Injectable } from '@angular/core';
declare const $: any;
@Injectable()
export class SignalRService {
// Declare the variables
private proxy: any;
private connection: any;
private authData: any;
// create the Event Emitter
public messageReceived: EventEmitter<any>;
public connectionEstablished: EventEmitter<Boolean>;
public connectionExists: Boolean;
constructor(private appSettings: AppSettings) {
// Setup
this.connectionEstablished = new EventEmitter<Boolean>();
this.messageReceived = new EventEmitter<any>();
this.connectionExists = false;
}
public initialize(proxyName: string): void {
this.connection = $.hubConnection(this.appSettings.SIGNALR_BASE_URL);
this.proxy = this.connection.createHubProxy(proxyName);
this.registerOnServerEvents();
this.startConnection();
}
private startConnection(): void {
this.connection.start({withCredentials: false})
.done((data: any) => {
console.log('SignalR Connected with: ' + data.transport.name);
this.connectionEstablished.emit(true);
this.connectionExists = true;
})
.fail((error: any) => {
console.log('SignalR could not connect: ' + error);
this.connectionEstablished.emit(false);
});
}
private registerOnServerEvents() {
this.proxy.on('listUpdated', (list: any) => {
console.log(list);
this.messageReceived.emit(list);
});
}
}
initialize (proxyName) вызывается из контроллера для установления соединения с концентратором.
UPDATE
Я пытался восстановить сервер и концентратор с помощью .NET Core 2.0, но при тестировании этого на сервере IIS получаю:
"Не удалось загрузитьhttps://signalr.example.com/online/negotiate: Ответ на предварительный запрос не проходит проверку контроля доступа: на запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Следовательно, Origin 'https://example.com' не имеет доступа."
Так что это все еще проблема CORS, хотя я настроил все так же, как несколько руководств.