无法使用 OWIN Self Host 关闭和启动新的 SignalR
Cannot shut down and start new SignalR using OWIN Self Host
在 1.5 周的重构结束时,这是一堵难撞的墙。
我已经把它降到最低限度,我完全亏本了
我使用 owin selfhost (katana) 启动了一个 SignalR 网络服务器,并连接到它。我关闭它,然后启动它并尝试再次连接它。
在第 秒 时间(第一次工作正常)我在尝试启动连接时遇到错误:
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
using (var server = new TestWebServer()) {
server.Start();
using (var hubConnection = new HubConnection(TestWebServer.Host)) {
var proxy = hubConnection.CreateHubProxy("testHub");
hubConnection.Start().Wait();
Debug.Assert(hubConnection.State == ConnectionState.Connected);
}
}
// Makes it here fine
using (var server = new TestWebServer()) {
server.Start();
using (var hubConnection = new HubConnection(TestWebServer.Host)) {
var proxy = hubConnection.CreateHubProxy("testHub");
hubConnection.Start().Wait(); //<-throws "Transport timed out trying to connect"
Debug.Assert(hubConnection.State == ConnectionState.Connected);
}
}
}
}
与TestWebServer
:
public class TestWebServer : IDisposable {
public const string Host = "http://localhost:8081/";
public void Start() {
if (null != server) return;
this.server = WebApp.Start(Host, app => {
var cfg = new HubConfiguration { };
app.MapSignalR(cfg);
});
}
IDisposable server;
//Super-duper-for-real disposable https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/
bool _disposed;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
~TestWebServer() {
Dispose(false);
}
protected virtual void Dispose(bool disposing) {
if (_disposed)
return;
if (disposing) {
if (null == server) return;
server.Dispose();
server = null;
}
_disposed = true;
}
}
和TestHub
[HubName("testHub")]
public class TestHub : Hub {
public void Ping() => Clients.All.pong();
}
这是使用 SignalR 2.2.0,我在 .Net 4.5 和 4.6.1 上都试过了
这是我可能知道如何制作的最简单的 SignalR 应用程序,您会发现它可以工作!一次。然后当我处理并再次尝试完全相同的代码时它失败了。
这是怎么回事?我还需要做些什么来处理东西吗?
是的,我试过Thread.Sleep
两者之间。
感谢我的同事 Shamus,他发现 this article 然后怀疑地破解了我的演示项目,直到该死的东西成功。
如果您每次都给HubConfiguration
一个Resolver
的新实例,您可以停止并重新启动。换句话说 check this nonsense out in the source.
换句话说,做
var cfg = new HubConfiguration { Resolver = new DefaultDependencyResolver() };
为了解决所有问题的美好时光。
SO 目前看来,存储在依赖项解析器中的某些内容没有得到妥善处理。 (由于在网络服务器处置期间发生异常并记录到调试输出,这一事实加剧了这种怀疑)。如果您不是每次都手动创建自己的解析器,那么...恭喜您,您只是在获取包含未正确处理的对象的同一个全局解析器。
所以答案似乎是肯定的,这是一个 SignalR 错误,但也是肯定的,有一个简单的解决方法。
在 1.5 周的重构结束时,这是一堵难撞的墙。
我已经把它降到最低限度,我完全亏本了
我使用 owin selfhost (katana) 启动了一个 SignalR 网络服务器,并连接到它。我关闭它,然后启动它并尝试再次连接它。
在第 秒 时间(第一次工作正常)我在尝试启动连接时遇到错误:
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
using (var server = new TestWebServer()) {
server.Start();
using (var hubConnection = new HubConnection(TestWebServer.Host)) {
var proxy = hubConnection.CreateHubProxy("testHub");
hubConnection.Start().Wait();
Debug.Assert(hubConnection.State == ConnectionState.Connected);
}
}
// Makes it here fine
using (var server = new TestWebServer()) {
server.Start();
using (var hubConnection = new HubConnection(TestWebServer.Host)) {
var proxy = hubConnection.CreateHubProxy("testHub");
hubConnection.Start().Wait(); //<-throws "Transport timed out trying to connect"
Debug.Assert(hubConnection.State == ConnectionState.Connected);
}
}
}
}
与TestWebServer
:
public class TestWebServer : IDisposable {
public const string Host = "http://localhost:8081/";
public void Start() {
if (null != server) return;
this.server = WebApp.Start(Host, app => {
var cfg = new HubConfiguration { };
app.MapSignalR(cfg);
});
}
IDisposable server;
//Super-duper-for-real disposable https://lostechies.com/chrispatterson/2012/11/29/idisposable-done-right/
bool _disposed;
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
~TestWebServer() {
Dispose(false);
}
protected virtual void Dispose(bool disposing) {
if (_disposed)
return;
if (disposing) {
if (null == server) return;
server.Dispose();
server = null;
}
_disposed = true;
}
}
和TestHub
[HubName("testHub")]
public class TestHub : Hub {
public void Ping() => Clients.All.pong();
}
这是使用 SignalR 2.2.0,我在 .Net 4.5 和 4.6.1 上都试过了
这是我可能知道如何制作的最简单的 SignalR 应用程序,您会发现它可以工作!一次。然后当我处理并再次尝试完全相同的代码时它失败了。
这是怎么回事?我还需要做些什么来处理东西吗?
是的,我试过Thread.Sleep
两者之间。
感谢我的同事 Shamus,他发现 this article 然后怀疑地破解了我的演示项目,直到该死的东西成功。
如果您每次都给HubConfiguration
一个Resolver
的新实例,您可以停止并重新启动。换句话说 check this nonsense out in the source.
换句话说,做
var cfg = new HubConfiguration { Resolver = new DefaultDependencyResolver() };
为了解决所有问题的美好时光。
SO 目前看来,存储在依赖项解析器中的某些内容没有得到妥善处理。 (由于在网络服务器处置期间发生异常并记录到调试输出,这一事实加剧了这种怀疑)。如果您不是每次都手动创建自己的解析器,那么...恭喜您,您只是在获取包含未正确处理的对象的同一个全局解析器。
所以答案似乎是肯定的,这是一个 SignalR 错误,但也是肯定的,有一个简单的解决方法。