【发布时间】:2019-03-13 14:13:58
【问题描述】:
我在 Windows Server 2012 上托管一个 SignalR 集线器,将 IIS 作为 ASP.NET Web 应用程序,我已在本地计算机上成功测试过该应用程序。但是,当我发布并尝试从 Angular 应用程序连接时,服务器会在 /negotiate 请求上响应 403 Forbidden。 Angular 应用程序与 Hub 服务器位于不同的域中。
我了解到这是由 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 应用程序 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) 从控制器调用以启动与 Hub 的连接。
更新
我尝试使用 .NET Core 2.0 重建服务器和集线器,但是当我在 IIS 服务器上进行测试时,我得到:
“加载 https://signalr.example.com/online/negotiate 失败:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。来源“https://example.com”因此不允许访问。”
因此,即使我已经像多个指南一样设置了所有内容,这仍然是一个 CORS 问题。
【问题讨论】:
标签: javascript c# asp.net angular signalr