我有一个聊天应用程序在Visual Studio 2017下使用IIS express进行本地调试时运行正常。在我将其解密为生产(Windows服务器2012R2 IIS 8.5.9600)后,javascript控制台向我发送消息:
“WebSocket连接到'wss:// [myServer] / [myHubName]?id = [weirdString]'失败:WebSocket握手期间出错:意外响应代码:200”
虽然客户端使用https访问网站,但ssl解密是在防火墙上执行的,因此传入的https请求在端口8088上以http的形式到达服务器。
还尝试将我的网站URL放在IIS上的站点绑定上的“hostname”选项中,但随后该站点开始返回错误400。
我已经在IIS上安装了WebSockets支持,如microsoft documentation所述,并确保我的网站已启用它。
我还在服务器(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
关于如何解决这个问题的任何想法?
我的启动代码中的代码段是:
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?}");
});
}
}
Program.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();
}
现在我更了解你的问题,确保你的IIS绑定设置为所有ipaddresses上的listen,Type = http,hostname =你从WAN使用的url,ipaddress = *,Port = 8088
注意:您在评论中说8088是从防火墙到您的服务器来访问该应用程序。因此,您不是在服务器上使用https,而是使用http,并且防火墙已经对传入流量进行了加密。您不希望在路由中加密两次流量。
你还说它在服务器上本地工作,所以发生了两件事之一:
由于2正在发生,部分根据您的更新,您需要在某处重写URL,这可能会有所帮助:
Websockets reverse proxy in IIS 8
也许不完全是这样,但重写您发送回客户端的流量以删除端口以匹配用户用于从客户端连接的URL。客户端不知道WAN的8088端口。