SignalR客户端Owin重启后重新连接,但消息未发布 [英] SignalR client is reconnected after Owin restart, but message is not published
问题描述
设置:
- SignalRServer控制台应用程序:Microsoft.AspNet.SignalR.SelfHost V2.0.3
- SignalRClient控制台应用程序:Microsoft.AspNet.SignalR.Client V2.0.3
- .NET 4.5.1
块引用>我做到以下几点:
- 点击客户端进入,在服务器和客户端收到消息再次
- 将击中服务器控制台任意键处置服务器
- 将击中服务器控制台任意键重新启动服务器
- 客户端重新连接
- 点击客户端输入,消息在服务器接收,但从来没有再次达到客户
块引用>我期望能够在客户端再次收到消息。我怀疑它是与自托管,因为我已经尝试运行对同一集线器客户端在Web应用程序运行IIS成功。
任何想法?
更新:如果服务器控制台进程被终止并重新启动,它能够再次重新连接和检索信息
服务器code
使用系统;
使用System.Threading.Tasks;
使用Microsoft.AspNet.SignalR;
使用Microsoft.Owin.Hosting;
使用Owin;命名空间SignalRServer
{
内部类节目
{
私有静态无效的主要(字串[] args)
{
常量字符串URL =HTTP://本地主机:8081; 而(真)
{
使用(WebApp.Start<&启动GT;(URL))
{
Console.WriteLine(服务器{0}按下任意键停止运行。,URL);
到Console.ReadLine();
} Console.WriteLine(服务器停止); Console.WriteLine(打任意键重新启动,Esc退出); ConsoleKeyInfoき= Console.ReadKey(真); 如果(ki.Key == ConsoleKey.Escape)
返回;
}
}
} 公共类启动
{
公共无效配置(IAppBuilder应用程序)
{
app.MapSignalR();
}
} 公共类AuthenticationHub:集线器
{
公共无效BroadcastMessageToAll(字符串消息)
{
Clients.All.sendMessageToClient(消息);
Console.WriteLine(sendMessageToClient:+消息);
} 公众覆盖任务OnConnected()
{
Console.WriteLine(OnConnected+ Context.ConnectionId);
返回base.OnConnected()
} 公众覆盖任务OnReconnected()
{
Console.WriteLine(OnReconnected+ Context.ConnectionId);
返回base.OnReconnected();
} 公众覆盖任务OnDisconnected()
{
Console.WriteLine(OnDisconnected+ Context.ConnectionId);
返回base.OnReconnected();
}
}
}客户端code
使用系统;
使用Microsoft.AspNet.SignalR.Client;命名空间SignalRClient
{
类节目
{
静态无效的主要(字串[] args)
{
而(真)
{
VAR hubConnection =新HubConnection(HTTP://本地主机:8081 / signalr /集线器); hubConnection.Closed + =()=> Console.WriteLine(封闭);
hubConnection.StateChanged + = E => Console.WriteLine(StateChanged:+ e.OldState ++ e.NewState);
变种hubProxy = hubConnection.CreateHubProxy(AuthenticationHub); hubProxy.On<串GT(sendMessageToClient
信息=> Console.WriteLine(sendMessageToClient收到:+资讯));
hubConnection.Start(); Console.WriteLine(客户端开始 - 按Enter键发送消息 - ESC停止); Console.ReadKey(); 而(真)
{
VAR的密钥信息= Console.ReadKey(真); 如果(keyInfo.Key == ConsoleKey.Escape)
打破; VAR消息=控制台客户端:+ DateTime.Now.ToString(HH:MM:SS-FFF);
hubProxy.Invoke(BroadcastMessageToAll,邮件);
Console.WriteLine(客户端发送BroadcastMessageToAll:+消息);
} Console.WriteLine(客户停止); hubConnection.Stop(); Console.WriteLine(客户停止 - 再输入任意键启动);
到Console.ReadLine();
}
}
}
}
解决方案该SignalR团队向我指出的解决方案:
默认情况下SignalR使用GlobalHost,这是一个单解析器。处置时,就再也不会回来了。在创建轮毂的配置,你应该通过旅店一个新的依赖解析器:
公共类启动
{
公共无效配置(IAppBuilder应用程序)
{
VAR hubConfiguration =新HubConfiguration {解析器=新DefaultDependencyResolver()};
app.MapSignalR(hubConfiguration);
}
}Setup:
- SignalRServer console app: Microsoft.AspNet.SignalR.SelfHost v2.0.3
- SignalRClient console app: Microsoft.AspNet.SignalR.Client v2.0.3
- .NET 4.5.1
I do the following:
- Hit enter on client, a message is received at server and on client again
- Dispose the server by hitting any key in the server console
- Restart the server by hitting any key in the server console
- Client is reconnected
- Hit enter on client, message is received at server, but never reaches the client again
I expect the message to be received at the client again. I suspect it has something to do with the self-hosting, since I've tried to run the client against same hub in a web application running IIS with success.
Any ideas?
Update: if the server console process is killed and restarted, it is able to reconnect AND retrieve messages again.
Server code
using System; using System.Threading.Tasks; using Microsoft.AspNet.SignalR; using Microsoft.Owin.Hosting; using Owin; namespace SignalRServer { internal class Program { private static void Main(string[] args) { const string url = "http://localhost:8081"; while (true) { using (WebApp.Start<Startup>(url)) { Console.WriteLine("Server running on {0}. Hit any key to stop.", url); Console.ReadLine(); } Console.WriteLine("Server stopped"); Console.WriteLine("Hit any key to restart, Esc to exit"); ConsoleKeyInfo ki = Console.ReadKey(true); if (ki.Key == ConsoleKey.Escape) return; } } } public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } public class AuthenticationHub : Hub { public void BroadcastMessageToAll(string message) { Clients.All.sendMessageToClient(message); Console.WriteLine("sendMessageToClient: " + message); } public override Task OnConnected() { Console.WriteLine("OnConnected " + Context.ConnectionId); return base.OnConnected(); } public override Task OnReconnected() { Console.WriteLine("OnReconnected " + Context.ConnectionId); return base.OnReconnected(); } public override Task OnDisconnected() { Console.WriteLine("OnDisconnected " + Context.ConnectionId); return base.OnReconnected(); } } }
Client code
using System; using Microsoft.AspNet.SignalR.Client; namespace SignalRClient { class Program { static void Main(string[] args) { while (true) { var hubConnection = new HubConnection("http://localhost:8081/signalr/hubs"); hubConnection.Closed += () => Console.WriteLine("Closed"); hubConnection.StateChanged += e => Console.WriteLine("StateChanged: " + e.OldState + " " + e.NewState); var hubProxy = hubConnection.CreateHubProxy("AuthenticationHub"); hubProxy.On<string>("sendMessageToClient", info => Console.WriteLine("sendMessageToClient received: " + info)); hubConnection.Start(); Console.WriteLine("Client started - hit Enter to send a message - ESC to stop"); Console.ReadKey(); while (true) { var keyInfo = Console.ReadKey(true); if (keyInfo.Key == ConsoleKey.Escape) break; var message = "Console client : " + DateTime.Now.ToString("HH:mm:ss-fff"); hubProxy.Invoke("BroadcastMessageToAll", message); Console.WriteLine("Client sent BroadcastMessageToAll: " + message); } Console.WriteLine("Client stopping"); hubConnection.Stop(); Console.WriteLine("Client stopped - enter any key start again"); Console.ReadLine(); } } } }
解决方案The SignalR team pointed me to the solution: By default SignalR uses GlobalHost, which is a singleton resolver. When disposed, it will never come back.
When creating the configuration for the hub, you should pass inn a new dependency resolver:
public class Startup { public void Configuration(IAppBuilder app) { var hubConfiguration = new HubConfiguration {Resolver = new DefaultDependencyResolver()}; app.MapSignalR(hubConfiguration); } }
这篇关于SignalR客户端Owin重启后重新连接,但消息未发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!