簡體   English   中英

SignalR更改端口-SelfHost

[英]SignalR change port - SelfHost

我正在嘗試使用遠程請求更改服務器的端口。 當我這樣做時,似乎一切正常,但是當我嘗試連接時,出現異常。

如果我關閉(終止進程),然后打開(啟動進程)服務器,則使用新端口的所有端口都將正常運行(客戶端將設法連接)。

服務器:

internal class Program
{
    private static IDisposable _webApp = null;
    static void Main(string[] args)
    {
        var uri = Start(8089);
        Stop();
        var uri = Start(8089);
        Console.WriteLine("Press enter to exit");
        Console.ReadLine();
    }

    private static string Start(int port)
    {
        var options = new StartOptions();
        var uri = string.Format("http://*:{0}/", port);
        options.Urls.Add(uri);
        options.Settings.Add(typeof(ITraceOutputFactory).FullName, typeof(NullTraceOutputFactory).AssemblyQualifiedName);// disable built-in owin tracing by using a null traceoutput
        var startup = new Startup
            {
                Restart = Restart
            };
        _webApp = WebApp.Start(options, startup.Configuration);
        Trace.Listeners.Remove("HostingTraceListener"); // remove the built-in owin listener
        Console.WriteLine("Server running at " + uri);
        return uri;
    }

    private static void Stop()
    {
        _webApp.Dispose();
    }

    private static string Restart(int port)
    {
        Stop();
        var uri = Start(port);
        return uri;
    }

    internal class NullTraceOutputFactory : ITraceOutputFactory
    {
        public TextWriter Create(string outputFile)
        {
            return StreamWriter.Null;
        }
    }
}

[HubName("Configuration")]
public class ConfigurationHub : Hub
{
    private Func<int, string> _restart;

    public ConfigurationHub(Func<int, string> restart)
    {
        _restart = restart;
    }

    public void ChangePort(int port)
    {
        Console.WriteLine("Port: " + port);
        _restart(port);
    }
}

internal class Startup
{
    public Func<int, string> Restart;

    public void Configuration(IAppBuilder app)
    {
        GlobalHost.DependencyResolver.Register(typeof(ConfigurationHub),
                () => new ConfigurationHub(Restart));
        app.UseCors(CorsOptions.AllowAll);
        //app.UseWelcomePage();
        var hubConfiguration = new HubConfiguration
        {
            EnableJSONP = true,
#if DEBUG
            EnableDetailedErrors = true
#endif
        };

        app.MapSignalR(hubConfiguration);
    }
}

客戶:

public partial class Form1 : Form
{
    private IHubProxy _configurationProxy = null;
    private HubConnection _hubConnection;
    private const string CATEGORY = "ABCD";

    public Form1()
    {
        InitializeComponent();
        CreateProxy(8089);
        _hubConnection.Start().Wait();
    }

    private void btnChangePort_Click(object sender, EventArgs e)
    {
        var newPort = Int32.Parse(btnChangePort.Tag as string);
        _configurationProxy.Invoke("ChangePort", newPort);
        _hubConnection.Stop();
        _hubConnection.Dispose();
        _hubConnection = null;
        CreateProxy(newPort);
        _hubConnection.Start().Wait(); // <= Exception when clicking the button
    }

    private void CreateProxy(int newPort)
    {
        //var address = "127.0.0.1";
        var address = "192.168.0.100";
        var port = newPort;
        var config =
            new
                {
                    Name = "Configuration",
                    Pattern = "http://{0}:{1}",
                    Address = address,
                    Port = newPort,
                    QueryString = new Dictionary<string, string> { { "version", "1.0" } },
                    Methods = new[]
                        {
                            "notifyWrongVersion",
#if ERROR
                                "notifyConnected",
#endif
                            //"status",
                            "notifyByeBye"
                        },
                    MethodsCallbacks = new Action[]
                        {
                            () => Console.WriteLine("{0}: You are using the wrong version!", CATEGORY),
#if ERROR
                                    () => Trace.WriteLine("Connected to server! HOORAY!", Categories.CATEGORY_THIS),
#endif
                            () =>
                            Console.WriteLine("{0}: Bye bye from the server. Thank you for discnnecting.", CATEGORY)
                        },
                };

        var url = String.Format(config.Pattern, config.Address, config.Port);

        _hubConnection = new HubConnection(url);
        _hubConnection.TraceLevel = TraceLevels.All;
        _hubConnection.TraceWriter = Console.Out;
        _configurationProxy = _hubConnection.CreateHubProxy(config.Name);
    }
}

例外: 例外

場景:
從客戶端和服務器上的端口8089開始
按下客戶端和服務器上的按鈕更改為8088
關閉客戶
使用端口8088打開客戶端。

客戶端記錄:

14:04:18.2450308-空-ChangeState(已斷開連接,正在連接)14:04:18.7762877-708038b9-66b0-4cc2-95ac-de45411e453c-WS正在連接至:ws://192.168.250.9:8088 / signalr / connect?clientProtocol = 1.4&運輸=的WebSockets&connectionData = [{ “名稱”: “配置”}]&connectionToken = AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVaJK6bsSpkyFVlk1Ej463gAAAAACAAAAAAADZgAAwAAAABAAAAAcSxXM3loQOfD31c8mYLdqAAAAAASAAACgAAAAEAAAAISDmfaiIg%2BY%2FVt3bBI%2BZkAoAAAAd%2FngqVkiFGH55BN9NOW4nljYZzHBBwoTLxNwrj%2B31AiShmmgS6euMBQAAADjFYeiwsjjJ%2BRVX92GYdozAkKthw%3D%3D 14:04:23.8220044 - 708038b9-66b0-4cc2 -95ac-de45411e453c-自動:無法使用傳輸WebSockets連接到。 System.TimeoutException:嘗試連接的傳輸超時14:04:23.8220044-708038b9-66b0-4cc2-95ac-de45411e453c-SSE:GET http://192.168.250.9:8088/signalr/connect?clientProtocol=1.4&transport=serverSentEvents&connectionData= [ { “名稱”: “配置”}]&connectionToken = AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVaJK6bsSpkyFVlk1Ej463gAAAAACAAAAAAADZgAAwAAAABAAAAAcSxXM3loQOfD31c8mYLdqAAAAAASAAACgAAAAEAAAAISDmfaiIg%2BY%2FVt3bBI%2BZkAoAAAAd%2FngqVkiFGH55BN9NOW4nljYZzHBBwoTLxNwrj%2B31AiShmmgS6euMBQAAADjFYeiwsjjJ%2BRVX92GYdozAkKthw%3D%3D 14:04:23.9157549 - 708038b9-66b0-4cc2-95ac-de45411e453c - WS:OnClose()14:04:23.9157549-708038b9-66b0-4cc2-95ac-de45411e453c-SSE:OnMessage(數據:已初始化)14:04:28.8486354-708038b9-66b0-4cc2-95ac-de45411e453c-自動:無法連接使用傳輸serverSentEvents。 System.TimeoutException:嘗試連接的傳輸超時14:04:28.8642594-708038b9-66b0-4cc2-95ac-de45411e453c-LP連接: http : //192.168.250.9 :8088/signalr/connect?clientProtocol=1.4&transport=longPolling&connectionData= [ { “名稱”: “配置”}]&connectionToken = AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVaJK6bsSpkyFVlk1Ej463gAAAAACAAAAAAADZgAAwAAAABAAAAAcSxXM3loQOfD31c8mYLdqAAAAAASAAACgAAAAEAAAAISDmfaiIg%2BY%2FVt3bBI%2BZkAoAAAAd%2FngqVkiFGH55BN9NOW4nljYZzHBBwoTLxNwrj%2B31AiShmmgS6euMBQAAADjFYeiwsjjJ%2BRVX92GYdozAkKthw%3D%3D 14:04:33.8799023 - 708038b9-66b0-4cc2-95ac-de45411e453c -自動:使用傳輸longPolling無法連接。 System.TimeoutException:嘗試連接的傳輸超時14:04:33.8799023-708038b9-66b0-4cc2-95ac-de45411e453c-斷開連接14:04:33.8799023-708038b9-66b0-4cc2-95ac-de45411e453c-Transport.Dispose(708038b9-66b0 -4cc2-95ac-de45411e453c)14:04:33.8799023-708038b9-66b0-4cc2-95ac-de45411e453c-已關閉

3次后收到此錯誤,我也得到這個:

14:14:24.0350106-空-OnError(System.TimeoutException:自2015年5月31日起客戶端處於非活動狀態14:13:27且已超過非活動超時時間00:00:50。正在停止連接。)

我設法通過以下更改使其工作:

1)讓客戶端和服務器有時間在斷開連接(客戶端)或處置(服務器)之前完成

服務器:

public void ChangePort(int port)
{
    Console.WriteLine("Received ChangePort request: " + port);
    Task.Delay(500).ContinueWith(_ => _restart(port));
}

客戶:

_configurationProxy.Invoke("ChangePort", port)
    .ContinueWith(task =>
    {
        if (task.IsFaulted)
        {
            Console.WriteLine("ChangePort faulted: {0}", task.Exception.Flatten()); 
        }

        _hubConnection.Stop();
        _hubConnection.Dispose();
        _hubConnection = null;
    }).Wait();

2)似乎有一個問題,就是在服務器處置期間DependencyResolver被處置,並且再也不會回來(請參閱GitHub問題 )。 這樣的問題描述了您遇到的非常相似的問題。 這是解決方案:

internal class Startup
    {
        public Func<int, string> Restart;

        public void Configuration(IAppBuilder app)
        {
            var resolver = new DefaultDependencyResolver();
            resolver.Register(typeof(ConfigurationHub), () => new ConfigurationHub(Restart));

            var hubConfiguration = new HubConfiguration
            {
                EnableJSONP = true,
                EnableDetailedErrors = true,
                Resolver = resolver
            };

            app.MapSignalR(hubConfiguration);
        }
    }

我們有類似的情況! 而不是更改端口,我需要重新啟動客戶端或服務器端。

我使用計時器和一個“已連接”全局標志來達到目的。 例如,如果未連接,則每隔5秒嘗試在客戶端中捕獲一次連接功能,除非沒有連接,第二次嘗試通常可以,除非沒有連接,否則通常在第一次嘗試中會失敗,因為服務器的重啟速度不夠快!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM