当客户端失去连接时,Linux/Mono SocketException 上的 SignalR Owin Self-Host [英] SignalR Owin Self-Host on Linux/Mono SocketException when clients lose connection

查看:22
本文介绍了当客户端失去连接时,Linux/Mono SocketException 上的 SignalR Owin Self-Host的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 Owin 在 ubuntu 服务器 14.04、单声道 3.2.8 上运行非常简单的自托管信号器服务器.(代码如下).

I'm running very simple signalr server self-hosted via Owin on ubuntu server 14.04, mono 3.2.8. (code below).

连接/断开连接在远程 Windows 服务器上以及当我将这些位部署到 linux 服务器时都可以正常工作.但是当一个客户端意外死亡而不是告诉信号器他正在断开连接时,那是我只在 linux 服务器上得到一个永无止境的 SocketException 的时候.windows server 大约 30 秒左右后断开客户端,但是 linux server 每隔 10 秒左右就会永远喷出 socketexception(也在下面).

Connecting/Disconnecting works fine on both a remote windows server and when I deploy the bits to the linux server. But when a client dies unexpectedly instead of telling signalr that he's disconnecting, that's when I get a never-ending SocketException only on the linux server only. The windows server disconnects the client after about 30 seconds or so, but the linux server spews the socketexception (also below) every 10 seconds or so, forever.

如何让 linux 服务器在运行相同的代码时表现得像 windows 服务器一样,在设置的超时后断开用户连接并且不抛出套接字异常?

How can I make the linux server behave like the windows server when running the same code, disconnect the user after a set timeout and not throw socketexceptions?

using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Owin;

namespace signalrtestserver
{
    class Program
    {
        static void Main(string[] args)
        {
            var uri = System.Configuration.ConfigurationManager.AppSettings["startup_uri"] ?? "http://*:7890";
            using (Microsoft.Owin.Hosting.WebApp.Start<Startup>(uri))
            {
                Console.WriteLine(string.Format("Server started on {0}. Press enter to close.", uri));
                Console.ReadLine();
            }
        }
    }

    class Startup
    {
        static Hub hub;

        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            var configuration = new HubConfiguration();
            configuration.EnableDetailedErrors = true;
            app.MapSignalR("/signalr", configuration);
            hub = new MyHub();
        }
    }

    public class MyHub : Hub
    {
        public override Task OnConnected() { Console.WriteLine(Context.ConnectionId + " connected"); return base.OnConnected(); }
        public override Task OnDisconnected() { Console.WriteLine(Context.ConnectionId + " disconnected"); return base.OnDisconnected(); }
        public override Task OnReconnected() { Console.WriteLine(Context.ConnectionId + " reconnected"); return base.OnReconnected(); }
    }
}

客户代码:

using System;
using System.Net;
using Microsoft.AspNet.SignalR.Client;

namespace signalrconnection
{
    class Program
    {
        static void Main(string[] args)
        {
            var uri = System.Configuration.ConfigurationManager.AppSettings["signalr_uri"] ?? "http://localhost:7890/signalr";
            ServicePointManager.DefaultConnectionLimit = 10;
            var hubConnection = new HubConnection(uri, false);
            hubConnection.StateChanged += stateChange => Console.WriteLine(string.Format("SignalR {0} >> {1} ({2})", stateChange.OldState, stateChange.NewState, hubConnection.Transport == null ? "<<null>>" : hubConnection.Transport.Name));
            var hubProxy = hubConnection.CreateHubProxy("MyHub");
            hubConnection.Start();
            Console.WriteLine("Press enter to die...");
            Console.ReadLine();
            //hubConnection.Dispose(); //uncomment this to simulate a graceful disconnect which works on both windows and linux
        }
    }
}

永无止境的单声道异常:

{path-to-project}/Microsoft.AspNet.SignalR.Core.dll Error : 0 : SignalR exception thrown by Task: System.AggregateException: One or more errors occured ---> System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: Connection reset by peer
  at System.Net.Sockets.Socket.Send (System.Byte[] buf, Int32 offset, Int32 size, SocketFlags flags) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.NetworkStream.Write (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Net.Sockets.NetworkStream.Write (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0
  at System.Net.ResponseStream.InternalWrite (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
  at System.Net.ResponseStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
  at Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
 --> (Inner exception 0) System.IO.IOException: Write failure ---> System.Net.Sockets.SocketException: Connection reset by peer
  at System.Net.Sockets.Socket.Send (System.Byte[] buf, Int32 offset, Int32 size, SocketFlags flags) [0x00000] in <filename unknown>:0
  at System.Net.Sockets.NetworkStream.Write (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Net.Sockets.NetworkStream.Write (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0
  at System.Net.ResponseStream.InternalWrite (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
  at System.Net.ResponseStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0
  at Microsoft.Owin.Host.HttpListener.RequestProcessing.ExceptionFilterStream.Write (System.Byte[] buffer, Int32 offset, Int32 count) [0x00000] in <filename unknown>:0

任何帮助将不胜感激.提前致谢!

Any help would be much appreciated. Thanks in advance!

推荐答案

问题出在static Hub hub这一行,而这一行hub = new MyHub()在你的启动方法.

The problem is this line static Hub hub, and this one hub = new MyHub() in your Startup method.

您不需要显式创建 Hub 类的实例,也不需要保留引用.对服务器的每个请求都会实例化集线器类.看http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#transienceHub 对象生命周期部分.

You do not need to explicitly create instances of the Hub class, neither do you need to keep a reference around. The hub class is instantiated on every request to the server. See http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#transience the section on Hub object lifetime.

这篇关于当客户端失去连接时,Linux/Mono SocketException 上的 SignalR Owin Self-Host的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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