SignalR 服务器 --> 客户端调用不工作
SignalR server --> client call not working
我目前正在使用 SignalR 在服务器和服务器本身产生的多个独立进程之间进行通信。
服务器和客户端都用 C# 编码。我正在使用 SignalR 2.2.0.0
在服务器端,我使用 OWIN 来 运行 服务器。
我还使用 LightInject 作为 IoC 容器。
这是我的代码:
public class AgentManagementStartup
{
public void ConfigurationOwin(IAppBuilder app, IAgentManagerDataStore dataStore)
{
var serializer = new JsonSerializer
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Auto,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
};
var container = new ServiceContainer();
container.RegisterInstance(dataStore);
container.RegisterInstance(serializer);
container.Register<EventHub>();
container.Register<ManagementHub>();
var config = container.EnableSignalR();
app.MapSignalR("", config);
}
}
在客户端,我是这样注册的:
public async Task Connect()
{
try
{
m_hubConnection = new HubConnection(m_serverUrl, false);
m_hubConnection.Closed += OnConnectionClosed;
m_hubConnection.TraceLevel = TraceLevels.All;
m_hubConnection.TraceWriter = Console.Out;
var serializer = m_hubConnection.JsonSerializer;
serializer.TypeNameHandling = TypeNameHandling.Auto;
serializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
m_managementHubProxy = m_hubConnection.CreateHubProxy(AgentConstants.ManagementHub.Name);
m_managementHubProxy.On("closeRequested", CloseRequestedCallback);
await m_hubConnection.Start();
}
catch (Exception e)
{
m_logger.Error("Exception encountered in Connect method", e);
}
}
在服务器端,我通过以下方式发送关闭请求:
var managementHub = GlobalHost.ConnectionManager.GetHubContext<ManagementHub>();
managementHub.Clients.All.closeRequested();
我从未在 CloseRequestedCallback
收到任何回电。无论是在客户端还是在服务器端,我都没有在日志中收到任何错误。
我做错了什么?
编辑 2015 年 9 月 10 日
经过研究和修改,我发现它与更换IoC容器有关。当我删除链接到 LightInject 的所有内容并按原样使用 SignalR 时,一切正常。自从 LightInject documented their integration with SignalR.
以来,我对此感到很惊讶
找到这个之后,我意识到 GlobalHost.DependencyResolver
和我提供给 HubConfiguration
的那个不一样。一旦我添加
GlobalHost.DependencyResolver = config.Resolver;
之前
app.MapSignalR("", config);
我现在在 CloseRequestedCallback
内收到回电。不幸的是,当我从客户端调用一个方法到服务器时,我得到了以下错误:
Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException
Possible deadlock detected. A callback registered with "HubProxy.On"
or "Connection.Received" has been executing for at least 10 seconds.
我不确定我找到的修复程序及其对系统的影响。在不注册所有默认内容的情况下用我自己的替换 GlobalHost.DependencyResolver
可以吗?
编辑 2 2015 年 9 月 10 日
根据 this,更改 GlobalHost.DependencyResolver
是正确的做法。仍然没有对 SlowCallbackException
的任何解释,因为我在所有回调中都没有做任何事情(还)。
问题 1:IoC 容器 + 依赖注入
如果您想为您更改 IoC HubConfiguration
,您还需要更改 GlobalHost
中的 IoC,以便 returns 在上下文之外请求它时使用相同的集线器.
问题 2:意外的 SlowCallbackException
此异常是由于我在控制台应用程序中使用 SignalR 造成的。应用程序的入口点不能是 async
方法,因此为了能够异步调用我的初始配置,我做了如下操作:
private static int Main()
{
var t = InitAsync();
t.Wait();
return t.Result;
}
对我来说不幸的是,这会导致很多问题 here & more in details here。
通过如下方式启动我的 InitAsync
:
private static int Main()
{
Task.Factory.StartNew(async ()=> await InitAsync());
m_waitInitCompletedRequest.WaitOne(TimeSpan.FromSeconds(30));
return (int)EndpointErrorCode.Ended;
}
现在一切正常,我没有遇到任何死锁。
关于问题和答案的更多细节,你也可以参考我问题中的编辑。
我目前正在使用 SignalR 在服务器和服务器本身产生的多个独立进程之间进行通信。 服务器和客户端都用 C# 编码。我正在使用 SignalR 2.2.0.0 在服务器端,我使用 OWIN 来 运行 服务器。 我还使用 LightInject 作为 IoC 容器。
这是我的代码:
public class AgentManagementStartup
{
public void ConfigurationOwin(IAppBuilder app, IAgentManagerDataStore dataStore)
{
var serializer = new JsonSerializer
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Auto,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
};
var container = new ServiceContainer();
container.RegisterInstance(dataStore);
container.RegisterInstance(serializer);
container.Register<EventHub>();
container.Register<ManagementHub>();
var config = container.EnableSignalR();
app.MapSignalR("", config);
}
}
在客户端,我是这样注册的:
public async Task Connect()
{
try
{
m_hubConnection = new HubConnection(m_serverUrl, false);
m_hubConnection.Closed += OnConnectionClosed;
m_hubConnection.TraceLevel = TraceLevels.All;
m_hubConnection.TraceWriter = Console.Out;
var serializer = m_hubConnection.JsonSerializer;
serializer.TypeNameHandling = TypeNameHandling.Auto;
serializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
m_managementHubProxy = m_hubConnection.CreateHubProxy(AgentConstants.ManagementHub.Name);
m_managementHubProxy.On("closeRequested", CloseRequestedCallback);
await m_hubConnection.Start();
}
catch (Exception e)
{
m_logger.Error("Exception encountered in Connect method", e);
}
}
在服务器端,我通过以下方式发送关闭请求:
var managementHub = GlobalHost.ConnectionManager.GetHubContext<ManagementHub>();
managementHub.Clients.All.closeRequested();
我从未在 CloseRequestedCallback
收到任何回电。无论是在客户端还是在服务器端,我都没有在日志中收到任何错误。
我做错了什么?
编辑 2015 年 9 月 10 日
经过研究和修改,我发现它与更换IoC容器有关。当我删除链接到 LightInject 的所有内容并按原样使用 SignalR 时,一切正常。自从 LightInject documented their integration with SignalR.
以来,我对此感到很惊讶找到这个之后,我意识到 GlobalHost.DependencyResolver
和我提供给 HubConfiguration
的那个不一样。一旦我添加
GlobalHost.DependencyResolver = config.Resolver;
之前
app.MapSignalR("", config);
我现在在 CloseRequestedCallback
内收到回电。不幸的是,当我从客户端调用一个方法到服务器时,我得到了以下错误:
Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException
Possible deadlock detected. A callback registered with "HubProxy.On" or "Connection.Received" has been executing for at least 10 seconds.
我不确定我找到的修复程序及其对系统的影响。在不注册所有默认内容的情况下用我自己的替换 GlobalHost.DependencyResolver
可以吗?
编辑 2 2015 年 9 月 10 日
根据 this,更改 GlobalHost.DependencyResolver
是正确的做法。仍然没有对 SlowCallbackException
的任何解释,因为我在所有回调中都没有做任何事情(还)。
问题 1:IoC 容器 + 依赖注入
如果您想为您更改 IoC HubConfiguration
,您还需要更改 GlobalHost
中的 IoC,以便 returns 在上下文之外请求它时使用相同的集线器.
问题 2:意外的 SlowCallbackException
此异常是由于我在控制台应用程序中使用 SignalR 造成的。应用程序的入口点不能是 async
方法,因此为了能够异步调用我的初始配置,我做了如下操作:
private static int Main()
{
var t = InitAsync();
t.Wait();
return t.Result;
}
对我来说不幸的是,这会导致很多问题 here & more in details here。
通过如下方式启动我的 InitAsync
:
private static int Main()
{
Task.Factory.StartNew(async ()=> await InitAsync());
m_waitInitCompletedRequest.WaitOne(TimeSpan.FromSeconds(30));
return (int)EndpointErrorCode.Ended;
}
现在一切正常,我没有遇到任何死锁。
关于问题和答案的更多细节,你也可以参考我问题中的编辑。