SignalR .NET Client Invoke引发异常

时间:2012-03-12 02:28:18

标签: .net client signalr

我正在尝试使用SignalR .Net客户端的控制台应用程序但是当我尝试在Hub上调用方法时出现错误。这是我的控制台应用程序的代码:

static void Main(string[] args)
{            
    var connection = new HubConnection("http://localhost/SignalRTest");
    var myHub = connection.CreateProxy("SignalRTest.Classes.service");

    myHub.On<string>("addMessage", text =>
    {
        Console.WriteLine(text);
    });

    connection.Start().ContinueWith(task =>
    {
        if (task.IsFaulted)
        {   
            Console.WriteLine("There was an error opening the connection: {0}", task.Exception.GetBaseException());
        }
        else {                        
            Console.WriteLine("Connected.");
        }
   }).Wait();


   myHub.Invoke("Send", "Message from console.").ContinueWith(task => {
       if (task.IsFaulted)
       {                
           Console.WriteLine("There was an error calling Send: {0}", task.Exception.GetBaseException());
       }
       else
       {
           Console.WriteLine("Send complete.");
       }

   });


   Console.ReadLine();

}

以下是服务器的Hub:

[HubName("service")]
public class ServiceHub : Hub
{
    public void Send(string message)
    {
        // Call the addMessage method on all clients
        Clients.addMessage(message);
    }
}

我认为控制台应用正确连接,因为它写出“已连接”。但是当它尝试在服务器上调用Send方法时,我收到以下错误:

System.Net.WebException:远程服务器返回错误:(500)内部服务器错误。    在System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)    在SignalR.HttpHelper。&lt;&gt; c_ DisplayClass2.b _0(IAsyncResult ar)    在System.Threading.Tasks.TaskFactory 1.FromAsyncCoreLogic(IAsyncResult iar, Func 2 endMethod,TaskCompletionSource`1 tcs)

谁能告诉我我做错了什么?感谢。

3 个答案:

答案 0 :(得分:4)

此问题似乎是由使用无效的集线器名称(使用CreateProxy时)引起的。奇怪的是,start方法没有失败,但我只测试了它,并获得了与使用不存在的集线器名称相同的行为。

答案 1 :(得分:0)

您尚未添加SignalR.hosting.AspNet dll,因此会创建此错误。因此,首先在服务器上包含SignalR.Hosting.AspNet的dll。

答案 2 :(得分:0)

对我来说,这是我的SignalR集线器需要依赖项注入参数的结果。即使将ShowDetailedErrors设置为true,该错误也会被很好地隐藏,除了Azure的服务器日志中以外,该错误已被掩盖。

您收到的错误是这样的:

System.MissingMethodException:
   at System.RuntimeTypeHandle.CreateInstance (mscorlib, Version=4.0.0.0, 
   Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.RuntimeType.CreateInstanceSlow (mscorlib, Version=4.0.0.0, 
   Culture=neutral, PublicKeyToken=b77a5c561934e089)
   at System.RuntimeType.CreateInstanceDefaultCtor (mscorlib, Version=4.0.0.0, 
   at Microsoft.AspNet.SignalR.Hubs.DefaultHubActivator.Create 
   (Microsoft.AspNet.SignalR.Core, Version=2.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35)

如您所见,我使用的是“ DefaultHubActivator”,它不知道如何管理喷油器参数。因此,我遵循了this很好的建议,该建议教了我如何使用Unity进行注射。

基本知识是您需要编写自己的集线器激活器,但是您可以继承默认的集线器激活器,然后对其进行扩展,以避免必须注册SignalR具有的数十个依赖项。

 public class SignalRUnityDependencyResolver : DefaultDependencyResolver
{
    private readonly IUnityContainer _container;
    public SignalRUnityDependencyResolver(IUnityContainer container)
    {
        _container = container ?? throw new ArgumentNullException(nameof(container));
    }

    public override object GetService(Type serviceType)
    {
        return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : base.GetService(serviceType);
    }

    public override IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.IsRegistered(serviceType) ? _container.ResolveAll(serviceType) : base.GetServices(serviceType);
    }
}

之后,您可以在“启动”中对其进行设置

app.Map("/signalr", map =>
        {
            var hubConfiguration = new HubConfiguration()
            {
                EnableJSONP = true,
                EnableDetailedErrors = true,
                Resolver = new SignalRUnityDependencyResolver(UnityConfig.GetContainer())
            };
            map.RunSignalR(hubConfiguration);
            logger.WriteInfo("Started signalr.");
        });

最后在Unity中注册您的中心

container.RegisterType<MyHub>(new InjectionFactory((obj) => new MyHub(obj.Resolve<ILogger>())));