【问题标题】:SignalR server --> client call not workingSignalR 服务器 --> 客户端调用不起作用
【发布时间】:2015-09-09 20:59:21
【问题描述】:

我目前正在使用 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 中收到任何回电。无论是在客户端还是在服务器端,我都不会在日志中收到任何错误。

我在这里做错了什么?

编辑 09/10/15

经过一番研究和修改,我发现它与更换 IoC 容器有关。当我删除与 LightInject 相关的所有内容并按原样使用 SignalR 时,一切正常。自从 LightInject documented their integration 使用 SignalR 以来,我对此感到很惊讶。

在我找到这个之后,我意识到GlobalHost.DependencyResolver 与我提供给HubConfiguration 的那个不一样。一旦我添加了

GlobalHost.DependencyResolver = config.Resolver;

之前

app.MapSignalR("", config);

我现在在CloseRequestedCallback 内收到回调。不幸的是,当我从客户端调用一个方法到服务器时,我得到了以下错误:

Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException

检测到可能的死锁。使用“HubProxy.On”注册的回调 或“Connection.Received”已执行至少 10 秒。

我不确定我找到的修复程序以及它可能对系统产生的影响。在不注册其所有默认内容的情况下,将GlobalHost.DependencyResolver 替换为我自己的是否可以?

编辑 2 09/10/15

根据this,更改GlobalHost.DependencyResolver 是正确的做法。仍然没有对SlowCallbackException 进行任何解释,因为我在所有回调中都没有做任何事情(还)。

【问题讨论】:

  • 关于你的慢回调,也许你需要执行那个慢进程in the background,然后使用SignalR来启动任务?无论如何,这是一个单独的问题。将您的 IoC 解决方案从您的问题中移出并给出答案。然后,如有必要,为您的慢速回调创建一个新问题。
  • @mason:我的任何回调(客户端和服务器端)中都没有任何长时间运行的进程。这就是为什么我对这个错误感到惊讶。我理解您将问题保留在同一主题内的观点,但问题似乎相关。

标签: c# signalr owin light-inject


【解决方案1】:

问题一:IoC容器+依赖注入

如果您想为您更改 IoC HubConfiguration,您还需要更改 GlobalHost 中的那个,以便在上下文之外请求它时返回相同的集线器。

问题 2:意外的 SlowCallbackException

这个异常是由我在控制台应用程序中使用 SignalR 引起的。应用程序的入口点不能是 async 方法,因此为了能够异步调用我的初始配置,我执行以下操作:

private static int Main()
{
    var t = InitAsync();
    t.Wait();
    return t.Result;
}

对我来说不幸的是,这会导致很多问题,如here 所述以及更多详细信息here

如下开始我的InitAsync

private static int Main()
{
    Task.Factory.StartNew(async ()=> await InitAsync());
    m_waitInitCompletedRequest.WaitOne(TimeSpan.FromSeconds(30));
    return (int)EndpointErrorCode.Ended;
}

现在一切正常,我没有遇到任何死锁。

有关问题和答案的更多详细信息,您还可以参考我的问题中的编辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2021-08-25
    相关资源
    最近更新 更多