SignalR连接不会在单例类中启动

时间:2016-06-13 11:39:08

标签: c# singleton signalr

我在单例类中设置了signalR连接,因此我可以在整个项目中使用相同的连接。问题是连接永远不会启动,代码永远不会在行await hubConnection.Start()之外执行,但是当我在单个类之外执行此操作时,则会立即启动连接。我不知道我做错了什么。 这是我对单身人士课程的定义:

public sealed class ProxySubscriber
{
    private static volatile ProxySubscriber instance;
    private static object syncRoot = new Object();
    private IHubProxy chatHubProxy = null;
    private HubConnection hubConnection = null;
    public event Action<string, string> OnConnect;
    private ProxySubscriber()
    {
        if (hubConnection == null) { hubConnection = new HubConnection("http://cforbeginners.com:901"); }
        if (chatHubProxy == null) { chatHubProxy = hubConnection.CreateHubProxy("ChatHub"); }

        chatHubProxy.On<string, string>("onConnected", (id, username) => OnConnect.Invoke(id, username));
    }

    private async Task<string> StartConnection()
    {
        await hubConnection.Start();

        return "Connection started..";
    }

    public async void InvokeConnect()
    {
        await chatHubProxy.Invoke("Connect", "Mujtaba");
    }
    public static async Task<ProxySubscriber> GetInstance()
    {
        if (instance == null)
        {
            lock (syncRoot)
            {
                if (instance == null)
                {
                    instance = new ProxySubscriber();

                }
            }
        }

        await instance.StartConnection();
        return instance;
    }
}

我正在使用像这样的单身人士课程:

ProxySubscriber proxySubscriber = ProxySubscriber.GetInstance().Result;
proxySubscriber.OnConnect += proxySubscriber_OnConnect;
proxySubscriber.InvokeConnect();

1 个答案:

答案 0 :(得分:2)

首先,不要让你的GetInstance()异步。使用它只是为了创建一个没有更多逻辑的实例。

公开StartConnection并从外面拨打电话,等待通话:

await ProxySubscriber.GetInstance().StartConnection();
ProxySubscriber.GetInstance().OnConnect += proxySubscriber_OnConnect;
ProxySubscriber.GetInstance().InvokeConnect();

如果需要从非异步方法运行此代码:

Task.Factory.StartNew(async () => {
    await ProxySubscriber.GetInstance().StartConnection();
    ProxySubscriber.GetInstance().OnConnect += proxySubscriber_OnConnect;
    ProxySubscriber.GetInstance().InvokeConnect();
});

更多详情:

  1. 你的课程名称看起来不正确。像SignalRClientHelper
  2. 这样会更好
  3. 你不需要在构造函数上检查空值,因为它毫无疑问是空的if (hubConnection == null)
  4. 为什么服务器上有“连接”方法?当你await hubConnection.Start();进行连接时。如果您只想将用户名设置为连接,则可以在调用Start()之前在标头中传递该用户名:hubConnection.Headers.Add("username", "Mujtaba");
  5. 如果你想使这个类可靠,你需要处理SignalR断开连接(但这是一个不同的问题)
  6. 每当您致电chatHubProxy.Invoke("whatever");时,如果连接在某个时刻丢失,您可能会收到异常,这会导致您的应用程序崩溃。 Wrap it in a try/catch语句并根据需要处理异常。
  7. StartConnection应检查是否已建立连接。因此,如果您将其调用100次,则只会连接一次。
  8. 通常,您应该学习SignalR connection live cycle并在连接丢失时实现一些逻辑。

    查看hereherehere