我正在尝试使用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)
谁能告诉我我做错了什么?感谢。
答案 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>())));