SignalR 连接不会在单例中启动 class
SignalR connection wouldn't start inside a singleton class
我已经在单例中设置了我的 signalR 连接 class 所以我可以在我的整个项目中使用相同的连接。问题是连接永远不会启动并且代码永远不会在行 await hubConnection.Start()
之外执行,但是当我在单个 class 之外执行此操作时,连接会立即启动。我想知道我做错了什么。
这是我对单例的定义 class:
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;
}
}
我使用单例 class 是这样的:
ProxySubscriber proxySubscriber = ProxySubscriber.GetInstance().Result;
proxySubscriber.OnConnect += proxySubscriber_OnConnect;
proxySubscriber.InvokeConnect();
首先,不要让您的 GetInstance() 异步。仅使用它来创建一个没有更多逻辑的实例。
制作StartConnection
public从外面调用,等待调用:
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();
});
更多详情:
- 我觉得你的 class 名字不对。最好是
SignalRClientHelper
.
- 您不需要在构造函数上检查空值,因为毫无疑问它将为空
if (hubConnection == null)
- 为什么服务器上有 "Connect" 方法?当您执行
await hubConnection.Start();
时,您已经连接。如果您只想为连接分配一个用户名,您可以在调用 Start() 之前在 header 中传递该用户名:hubConnection.Headers.Add("username", "Mujtaba");
- 如果你想让这个 class 可靠,你需要处理 SignalR 断开连接(但这将是一个不同的问题)
- 每当您调用
chatHubProxy.Invoke("whatever");
时,如果连接在某个时候丢失,您可能会遇到异常,这会使您的应用程序崩溃。 Wrap it in a try/catch 语句并根据需要处理异常。
StartConnection
应该检查是否已经有连接。因此,如果您调用它 100 次,它只会连接一次。
一般来说,你应该学习SignalR connection live cycle,在连接丢失时实现一些逻辑。
我已经在单例中设置了我的 signalR 连接 class 所以我可以在我的整个项目中使用相同的连接。问题是连接永远不会启动并且代码永远不会在行 await hubConnection.Start()
之外执行,但是当我在单个 class 之外执行此操作时,连接会立即启动。我想知道我做错了什么。
这是我对单例的定义 class:
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;
}
}
我使用单例 class 是这样的:
ProxySubscriber proxySubscriber = ProxySubscriber.GetInstance().Result;
proxySubscriber.OnConnect += proxySubscriber_OnConnect;
proxySubscriber.InvokeConnect();
首先,不要让您的 GetInstance() 异步。仅使用它来创建一个没有更多逻辑的实例。
制作StartConnection
public从外面调用,等待调用:
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();
});
更多详情:
- 我觉得你的 class 名字不对。最好是
SignalRClientHelper
. - 您不需要在构造函数上检查空值,因为毫无疑问它将为空
if (hubConnection == null)
- 为什么服务器上有 "Connect" 方法?当您执行
await hubConnection.Start();
时,您已经连接。如果您只想为连接分配一个用户名,您可以在调用 Start() 之前在 header 中传递该用户名:hubConnection.Headers.Add("username", "Mujtaba");
- 如果你想让这个 class 可靠,你需要处理 SignalR 断开连接(但这将是一个不同的问题)
- 每当您调用
chatHubProxy.Invoke("whatever");
时,如果连接在某个时候丢失,您可能会遇到异常,这会使您的应用程序崩溃。 Wrap it in a try/catch 语句并根据需要处理异常。 StartConnection
应该检查是否已经有连接。因此,如果您调用它 100 次,它只会连接一次。
一般来说,你应该学习SignalR connection live cycle,在连接丢失时实现一些逻辑。