SignalR客户端Owin重启后重新连接,但消息未发布 [英] SignalR client is reconnected after Owin restart, but message is not published

查看:127
本文介绍了SignalR客户端Owin重启后重新连接,但消息未发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置:


  

      
  1. SignalRServer控制台应用程序:Microsoft.AspNet.SignalR.SelfHost V2.0.3

  2.   
  3. SignalRClient控制台应用程序:Microsoft.AspNet.SignalR.Client V2.0.3

  4.   
  5. .NET 4.5.1

  6.   

我做到以下几点:


  

      
  1. 点击客户端进入,在服务器和客户端收到消息再次

  2.   
  3. 将击中服务器控制台任意键处置服务器

  4.   
  5. 将击中服务器控制台任意键重新启动服务器

  6.   
  7. 客户端重新连接

  8.   
  9. 点击客户端输入,消息在服务器接收,但从来没有再次达到客户

  10.   

我期望能够在客户端再次收到消息。我怀疑它是与自托管,因为我已经尝试运行对同一集线器客户端在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:

  1. SignalRServer console app: Microsoft.AspNet.SignalR.SelfHost v2.0.3
  2. SignalRClient console app: Microsoft.AspNet.SignalR.Client v2.0.3
  3. .NET 4.5.1

I do the following:

  1. Hit enter on client, a message is received at server and on client again
  2. Dispose the server by hitting any key in the server console
  3. Restart the server by hitting any key in the server console
  4. Client is reconnected
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆