【发布时间】:2019-07-27 13:36:29
【问题描述】:
我有一个聊天应用程序,在 Visual Studio 2017 下使用 IIS Express 进行本地调试时运行良好。在我将它部署到生产环境(Windows server 2012R2 IIS 8.5.9600)后,javascript 控制台给我消息:
“与 'wss://[myServer]/[myHubName]?id=[weirdString]' 的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:200”
虽然客户端使用https访问网站,但在防火墙处进行ssl解密,因此传入的https请求以http的8088端口到达服务器。
还尝试将我的网站 URL 放在 IIS 上站点绑定的“主机名”选项上,但随后站点开始返回错误 400。
我已经按照microsoft documentation 中的说明在 IIS 上安装了 WebSockets 支持,并确保我的网站启用了它。
我也在服务器(http)本地浏览了网站,没有出现错误,看来是IIS反向代理配置的问题。
这里有一些 IIS 日志,省略了一些私人信息,来自 WAN 上的客户端和本地客户端的同一请求,在 IIS 运行的同一台机器上。
IIS log when access was performed from wan:
[lan server ip address] POST /[myHubName]/negotiate - 8088 - https://[public website url]/ 200 0 0 0
[lan server ip address] GET /[myHubName] id=zHiunn5_ynV2jO5812KpDg 8088 - https://[public website url]/ - 200 0 0 15
[lan server ip address] POST /[myHubName]/negotiate - 8088 - https://[public website url]/ 200 0 0 78
[lan server ip address] POST /[myHubName] id=T7M5A-o-qqTyd13dSMB64A 8088 - https://[public website url]/ 200 0 0 0
IIS log when access was performed locally on the IIS machine:
::1 POST /[myHubName]/negotiate - 8088 - ::1 http://localhost:8088/ 200 0 0 14
::1 GET /[myHubName] id=QY4do7yqF3EKRbS1Y3usuw 8088 - ::1 - 101 0 64 6356
两种方案的字段参考是:
#Fields: s-ip cs-method cs-uri-stem cs-uri-query s-port c-ip sc-status sc-substatus sc-win32-status time-taken
关于如何解决这个问题的任何想法?
我的启动代码中的 sn-ps 是:
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//ommited configuration: authorization, database connection, etc.
services.AddMvc(options =>
{
//some options;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//adds signalR
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCookiePolicy();
app.UseSession();
app.UseAuthentication();
app.UseSignalR(routes =>
{
routes.MapHub<MyHubName>("/MyHubName");
});
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
程序.cs:
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseKestrel()
.UseIISIntegration();
}
【问题讨论】:
-
您解决了吗?你能发布launchsettings.json吗?
-
您好 Jesse 我设法隔离了问题:反向代理 (apache) 弄乱了 websocket 标头。我最终会发布我是如何设法隔离问题的。但简短的故事是:我使用 IIS URL 重写模块来捕获在 IIS 上没有“升级:websocket”“连接:升级”标头的协商请求,并在将请求传递给服务器之前将这些标头注入到请求中.然后我注意到错误发生了变化,因为服务器响应了 101 所需的结果,但错误是缺少这些相同的标头。
-
有趣。从整体架构来看,管理 Apache 或 IIS 中的所有标头可能更好,但不能同时管理两者。我们总是让代理人员修复它:)
标签: c# websocket iis-8.5 asp.net-core-signalr