SignalR-在自托管进程中重新启动SignalR

SignalR-在自托管进程中重新启动SignalR,signalr,self-hosting,Signalr,Self Hosting,我已经让SignalR在自托管进程(当前是WinForm主机)中成功运行。客户端可以与浏览器连接并完美交互。当我需要在不完全终止主机进程的情况下重新启动游戏领域时,问题就出现了。在处理WebApp.Start()返回的IDisposable之后,我将重新加载所有业务数据,并再次调用WebApp.Start()。这似乎是可行的,没有出现异常或警告,但来自浏览器的客户端连接失败,无论是新的浏览器窗口还是选项卡。我在javascript中打开了信号器跟踪,并通过Fiddler捕获流量。/congoti

我已经让SignalR在自托管进程(当前是WinForm主机)中成功运行。客户端可以与浏览器连接并完美交互。当我需要在不完全终止主机进程的情况下重新启动游戏领域时,问题就出现了。在处理WebApp.Start()返回的IDisposable之后,我将重新加载所有业务数据,并再次调用WebApp.Start()。这似乎是可行的,没有出现异常或警告,但来自浏览器的客户端连接失败,无论是新的浏览器窗口还是选项卡。我在javascript中打开了信号器跟踪,并通过Fiddler捕获流量。/congotiate调用可以工作,但是WebSockets的/connect调用在5秒后超时,然后通过所有其他信号器回退失败。如果我完全终止主机进程并重新启动它,一切都会再次正常工作。通过每次终止整个过程来手动重启是不可行的。我打开了服务器端日志记录,下面是我看到的行为:

SignalR.Transports.TransportHeartBeat Information: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 is New.
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Information: 0 : Dispose(). Closing all connections
SignalR.Transports.WebSocketTransport Error: 0 : OnError(a9f279c9-9dcb-4cc2-806b-dd95e96561b4, System.Net.WebSockets.WebSocketException (0x80004005): An internal WebSocket error occurred. Please see the innerException, if present, for more details.  ---> System.Net.HttpListenerException (0x80004005): The I/O operation has been aborted because of either a thread exit or an application request
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.WebSocketHttpListenerDuplexStream.<ReadAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at System.Net.WebSockets.WebSocketBase.WebSocketOperation.<Process>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.WebSockets.WebSocketBase.<ReceiveAsyncCore>d__1.MoveNext()
   at System.Net.WebSockets.WebSocketBase.ThrowIfConvertibleException(String methodName, Exception exception, CancellationToken cancellationToken, Boolean aborted)
   at System.Net.WebSockets.WebSocketBase.<ReceiveAsyncCore>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.SignalR.WebSockets.WebSocketMessageReader.<ReadMessageAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler.<ProcessWebSocketRequestAsync>d__e.MoveNext())
SignalR.Transports.WebSocketTransport Information: 0 : End(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 exists. Closing previous connection.
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Information: 0 : Connection 263abf1d-aa32-41aa-af16-d64c530cd001 is New.
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 263abf1d-aa32-41aa-af16-d64c530cd001 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 263abf1d-aa32-41aa-af16-d64c530cd001 exists. Closing previous connection.
SignalR.Transports.ServerSentEventsTransport Information: 0 : End(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : Cancel(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : DrainWrites(263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.ServerSentEventsTransport Information: 0 : CompleteRequest (263abf1d-aa32-41aa-af16-d64c530cd001)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection a9f279c9-9dcb-4cc2-806b-dd95e96561b4 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(a9f279c9-9dcb-4cc2-806b-dd95e96561b4)
通过以下代码在自己的线程上运行:

public void Start()
{
    //threading/message stuffs
    if (!this.running)
    {
        this.running = true;
        ThreadStart ts = new ThreadStart(this.MainLoop);
        this.mainThread = new Thread(ts);
        this.mainThread.Start();
    }
    else
    {
        //message
    }
}
这是我的创业课程:

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseCors(CorsOptions.AllowAll);
        app.MapSignalR("/signalr", new HubConfiguration { EnableDetailedErrors = true, Resolver = new DefaultDependencyResolver() });
        app.RunSignalR();
    }
}
更新#2: 在操作中我可能不够清楚。除了使用Fiddler记录流量之外,我还启用了客户端的信号器跟踪。以下是浏览器中的输出:

[08:03:37] SignalR: Auto detected cross domain url.
[08:03:37] SignalR: Client subscribed to hub 'webmudhub'.
[08:03:37] SignalR: Negotiating with 'http://localhost:8080/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22webmudhub%22%7D%5D'.
[08:03:37] SignalR: webSockets transport starting.
[08:03:37] SignalR: Connecting to websocket endpoint 'ws://localhost:8080/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAecyNVO0bfE6%2BclQisGhh8QAAAAACAAAAAAAQZgAAAAEAACAAAACo51RwDaqYAC1N2%2FkMiQkuFhbVLfrH%2FfJEfdz9TV9F7AAAAAAOgAAAAAIAACAAAADrjqx8pyEMjZ%2BCkUHeZJcdwXH2LaSe1Qlh9XA7fo84MTAAAAB7mClxFPbknblDmZ8a14Thoa6FcLY7%2BS6fJpAXpeO8AaB8y5n4iCD6DotnQH07UDNAAAAA9eV4FLk1hr83h8NDy%2BWwKvGF%2FGn%2F00AOmn%2BMEfvcS5fa2xO%2F0Vd1sjd6TpJdTpePmakv1uOjTekP6FFYXVTU7g%3D%3D&connectionData=%5B%7B%22name%22%3A%22webmudhub%22%7D%5D&tid=0'.
[08:03:37] SignalR: Websocket opened.
[08:03:42] SignalR: webSockets transport timed out when trying to connect.
[08:03:42] SignalR: Closing the Websocket.
[08:03:42] SignalR: webSockets transport failed to connect. Attempting to fall back.
[08:03:42] SignalR: serverSentEvents transport starting.
[08:03:42] SignalR: Attempting to connect to SSE endpoint 'http://localhost:8080/connect?transport=serverSentEvents&clientProtocol=1.5…XVTU7g%3D%3D&connectionData=%5B%7B%22name%22%3A%22webmudhub%22%7D%5D&tid=3'.
[08:03:42] SignalR: EventSource connected.
[08:03:47] SignalR: serverSentEvents transport timed out when trying to connect.
[08:03:47] SignalR: EventSource calling close().
[08:03:47] SignalR: serverSentEvents transport failed to connect. Attempting to fall back.
[08:03:47] SignalR: longPolling transport starting.
[08:03:48] SignalR: Opening long polling request to 'http://localhost:8080/connect?transport=longPolling&clientProtocol=1.5&conn…kP6FFYXVTU7g%3D%3D&connectionData=%5B%7B%22name%22%3A%22webmudhub%22%7D%5D'.
[08:03:52] SignalR: longPolling transport timed out when trying to connect.
[08:03:52] SignalR: Aborted xhr request.
[08:03:52] SignalR: longPolling transport failed to connect. Attempting to fall back.
[08:03:52] SignalR: Fallback transports exhausted.
[08:03:52] SignalR: Stopping connection.
[08:03:52] SignalR: Fired ajax abort async = true.
注意:这是在处理完第一次连接后第二次调用WebApp.Start()后,通过新浏览器连接建立的全新连接上的。感觉信号机中的某些东西可能没有正确处理,导致一些遗留问题

这是另一个服务器端日志。我启动了服务器,停止了它(处理SignalR),并启动了它的备份(进行一个新的WebApp.Start()调用)。此时,它应该接受新的连接。相反,我看到的是:

SignalR.Transports.TransportHeartBeat Information: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 is New.
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : 92c4d8da-aeb5-4056-b274-625a83a366b1 is dead
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 exists. Closing previous connection.
SignalR.Transports.ServerSentEventsTransport Information: 0 : End(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : Cancel(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : DrainWrites(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Information: 0 : CompleteRequest (92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
我们再次看到新的连接,5秒钟后,CloseSocket()调用出于某种原因发出,可能是因为它认为它已经死了

我基本上是想遵循这个模式:

我知道这是一个Windows服务,而我的服务是托管在WinForm应用程序中的,所以可能这就是区别?我想知道Windows服务是否会在每个启动服务的请求上创建一个新的AppDomain。正如我所说的,如果我完全关闭WinForm应用程序并重新启动它,一切都会恢复正常


在我看来,我应该能够处理signar,然后通过另一次调用WebApp.Start()来启动它,但是第二次调用WebApp.Start不会出错,但它也不会正确地接受任何新的传入连接。他们暂停了。这显然是我的猜测,但可能是singleton模式或类似的内部信号器,在其IDisposable实现中没有正确处理?我选择WinForms是为了在开发过程中方便地将日志/通知记录到每个领域各自的WinForm主机,因为我将在每个Windows服务器上运行多个实例(每个实例在自己的端口上都有自己的SignalR实例)。

如果您可以发布重新启动的代码,这将非常有用,我用启动相关代码更新了帖子。我的Restart方法只是调用Stop方法,它只是将“stopping”设置为true,从而导致循环结束,然后在短暂的延迟后再次调用Start。您还应该尝试在客户端启用日志记录。它可能会透露出更多。。编辑:您应该注意到这一行:
signal.Transports.TransportHeartBeat信息:0:Dispose()。关闭所有连接
您正在执行的操作将触发Dispose()函数,该函数将关闭所有连接…更新帖子。我已经在使用客户端跟踪了。我不在乎关闭dispose上的现有连接,这很好。问题是在下一次WebApp.Start()调用后,没有新的连接被正确接受。非常确定,如果每次启动它时都将它塞进自己的AppDomain,它就会工作。现在要去验证这个理论,但那不起作用。重新启动后的任何新连接尝试仍然超时。我被难住了。也许我是唯一一个在WinForms主机上尝试此方案的人?
SignalR.Transports.TransportHeartBeat Information: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 is New.
SignalR.Transports.WebSocketTransport Information: 0 : CloseSocket(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : 92c4d8da-aeb5-4056-b274-625a83a366b1 is dead
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 exists. Closing previous connection.
SignalR.Transports.WebSocketTransport Information: 0 : End(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Verbose: 0 : Cancel(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Verbose: 0 : DrainWrites(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.WebSocketTransport Information: 0 : CompleteRequest (92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : Connection 92c4d8da-aeb5-4056-b274-625a83a366b1 exists. Closing previous connection.
SignalR.Transports.ServerSentEventsTransport Information: 0 : End(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : Cancel(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Verbose: 0 : DrainWrites(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.ServerSentEventsTransport Information: 0 : CompleteRequest (92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)
SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(92c4d8da-aeb5-4056-b274-625a83a366b1)