SignalR 在一台计算机上工作,但不能在其他计算机上工作
SignalR Working on One Computer But Not Others
我们有一个 Windows 服务托管 SignalR。同样的代码在不同的机器上运行,结果不同。
如果我在我的笔记本电脑上访问这个 link,它会起作用:
https://localhost/signalr/negotiate
回复:
{
"Url":"/signalr",
"ConnectionToken":"AQAAANCMnd8BFdERjHoAwE/...==",
"ConnectionId":"0a09e290-c8af-48d6-b791-f05e3b8930b0",
"KeepAliveTimeout":20.0,
"DisconnectTimeout":30.0,
"ConnectionTimeout":110.0,
"TryWebSockets":false,
"ProtocolVersion":"1.2",
"TransportConnectTimeout":5.0,
"LongPollDelay":0.0
}
如果我在桌面上转到相同的 link,我会得到:
我检查了 IE 设置,笔记本电脑和台式机之间的 TLS 设置相同。我还检查了许多其他 IE 设置。
编辑: 在好的 PC 上,在浏览器中获取证书警告。在非工作电脑上不会发生。
这是获取 SignalR 的代码 运行:
protected override void OnStart()
{
LogUtility.LogInformation("SignalRHubHostController::OnStart()");
string url = this.Application.Configuration.SignalRHubHostController.HostUrl;
UriBuilder uri = new UriBuilder(url);
string schemeOverride = this.Application.Configuration.SignalRHubHostController.UriSchemeOverride;
if (!String.IsNullOrWhiteSpace(schemeOverride))
uri.Scheme = schemeOverride;
LogUtility.LogInformation(String.Format(CultureInfo.InvariantCulture, "Using [{0}] as the SignalR hub URL.", uri.Uri.ToString()));
this._disposableWebServer = WebApp.Start<Startup>(uri.Uri.ToString());
}
internal class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
我成功了。显然这是现有证书设置为使用端口 443 的问题。我不知道为什么这是个问题,但以下步骤使事情开始为我工作。
注意:Rick Strahl 的博客帮助了:Hosting SignalR under SSL/https
- 专门为此目的在 IIS 中创建了证书:
注意:我不是必须使用 MMC 将证书从个人文件夹复制到受信任的根文件夹。它已经在受信任的根文件夹中。
- 删除专用于端口 443 的现有证书:
netsh http delete sslcert 0.0.0.0:443
注意:我最初尝试添加证书但出现错误,因为已经为端口 443 指定了证书。这就是为什么要在此处删除。
- 为端口 443 添加我的新证书:
netsh http add sslcert ipport=0.0.0.0:443
appid={12345678-db90-4b66-8b01-88f7af2e36bf}
certhash=hashGoesHere
注意:Rick Strahl 的博客说要始终使用该 appid。我不知道 appid 在证书的上下文中意味着什么。所以,是的,无论如何...
- 运行 我的应用程序并成功连接:
注意:我需要使用真实证书并信任它,这样我就不会再收到该警告。但这不是这个答案的重点。我只是想展示我是如何使用 SignalR 的。
所以虽然这让一切正常,但我不知道为什么专用于端口 443 的原始证书不起作用。也许它不在根存储中。我不知道如何根据 PC 上的哈希值找到该证书。
编辑
为了完整起见,我想分享一下如何获取证书哈希。您可以通过查看 IIS 中的证书手动键入它,也可以通过在 MMC 中查找它来复制它。这是证书的指纹 属性。您只需删除空格即可。
我们有一个 Windows 服务托管 SignalR。同样的代码在不同的机器上运行,结果不同。
如果我在我的笔记本电脑上访问这个 link,它会起作用:
https://localhost/signalr/negotiate
回复:
{
"Url":"/signalr",
"ConnectionToken":"AQAAANCMnd8BFdERjHoAwE/...==",
"ConnectionId":"0a09e290-c8af-48d6-b791-f05e3b8930b0",
"KeepAliveTimeout":20.0,
"DisconnectTimeout":30.0,
"ConnectionTimeout":110.0,
"TryWebSockets":false,
"ProtocolVersion":"1.2",
"TransportConnectTimeout":5.0,
"LongPollDelay":0.0
}
如果我在桌面上转到相同的 link,我会得到:
我检查了 IE 设置,笔记本电脑和台式机之间的 TLS 设置相同。我还检查了许多其他 IE 设置。
编辑: 在好的 PC 上,在浏览器中获取证书警告。在非工作电脑上不会发生。
这是获取 SignalR 的代码 运行:
protected override void OnStart()
{
LogUtility.LogInformation("SignalRHubHostController::OnStart()");
string url = this.Application.Configuration.SignalRHubHostController.HostUrl;
UriBuilder uri = new UriBuilder(url);
string schemeOverride = this.Application.Configuration.SignalRHubHostController.UriSchemeOverride;
if (!String.IsNullOrWhiteSpace(schemeOverride))
uri.Scheme = schemeOverride;
LogUtility.LogInformation(String.Format(CultureInfo.InvariantCulture, "Using [{0}] as the SignalR hub URL.", uri.Uri.ToString()));
this._disposableWebServer = WebApp.Start<Startup>(uri.Uri.ToString());
}
internal class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
我成功了。显然这是现有证书设置为使用端口 443 的问题。我不知道为什么这是个问题,但以下步骤使事情开始为我工作。
注意:Rick Strahl 的博客帮助了:Hosting SignalR under SSL/https
- 专门为此目的在 IIS 中创建了证书:
注意:我不是必须使用 MMC 将证书从个人文件夹复制到受信任的根文件夹。它已经在受信任的根文件夹中。
- 删除专用于端口 443 的现有证书:
netsh http delete sslcert 0.0.0.0:443
注意:我最初尝试添加证书但出现错误,因为已经为端口 443 指定了证书。这就是为什么要在此处删除。
- 为端口 443 添加我的新证书:
netsh http add sslcert ipport=0.0.0.0:443 appid={12345678-db90-4b66-8b01-88f7af2e36bf} certhash=hashGoesHere
注意:Rick Strahl 的博客说要始终使用该 appid。我不知道 appid 在证书的上下文中意味着什么。所以,是的,无论如何...
- 运行 我的应用程序并成功连接:
注意:我需要使用真实证书并信任它,这样我就不会再收到该警告。但这不是这个答案的重点。我只是想展示我是如何使用 SignalR 的。
所以虽然这让一切正常,但我不知道为什么专用于端口 443 的原始证书不起作用。也许它不在根存储中。我不知道如何根据 PC 上的哈希值找到该证书。
编辑
为了完整起见,我想分享一下如何获取证书哈希。您可以通过查看 IIS 中的证书手动键入它,也可以通过在 MMC 中查找它来复制它。这是证书的指纹 属性。您只需删除空格即可。