从 SignalR .NET 客户端连接到工作集线器时出现 HttpClientException

Posted

技术标签:

【中文标题】从 SignalR .NET 客户端连接到工作集线器时出现 HttpClientException【英文标题】:HttpClientException when connecting to working hub from SignalR .NET Client 【发布时间】:2015-08-10 17:13:36 【问题描述】:

我有一个可用的 SignalR 应用程序,它允许我连接多个 javascript 客户端并交换数据。当我尝试连接 .NET 客户端时,出现以下错误:

An exception of type 'Microsoft.AspNet.SignalR.Client.HttpClientException' occurred in mscorlib.dll but was not handled in user code

Additional information: StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:


  Transfer-Encoding: chunked
  X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcRGFycmVuXERlc2t0b3BcQ29uc29sZUFwcGxpY2F0aW9uMVxXZWJBcHBsaWNhdGlvbjFcc2lnbmFsclxuZWdvdGlhdGU=?=
  Cache-Control: private
  Date: Thu, 28 May 2015 09:13:06 GMT
  Server: Microsoft-IIS/8.0
  X-AspNet-Version: 4.0.30319
  X-Powered-By: ASP.NET
  Content-Type: text/html; charset=utf-8

为了尽可能多地删除变量,我将 Hub 复制到了一个全新的 Web 应用程序中,并将 .NET 客户端代码复制到了控制台应用程序中。我仍然得到同样的例外。这是我的客户端代码:

Dim hubConnection As HubConnection
Dim chatHubProxy As IHubProxy

Public Async Sub RunTest()
    System.Net.ServicePointManager.DefaultConnectionLimit = 10

    hubConnection = New HubConnection("http://localhost:64400")
    hubConnection.Credentials = Net.CredentialCache.DefaultCredentials
    hubConnection.TraceLevel = TraceLevels.All
    hubConnection.TraceWriter = Console.Out

    chatHubProxy = hubConnection.CreateHubProxy("Chat")

    AddHandler hubConnection.StateChanged, Sub(stateChange) Console.WriteLine("[" & DateTime.Now & "]: " & stateChange.OldState.ToString() & " =>  " & stateChange.NewState.ToString() & " " & hubConnection.ConnectionId)

    chatHubProxy.On(Of String, String)("ReceiveMessage", Sub(from, message) Console.WriteLine(message))
    Await hubConnection.Start()
End Sub

这是控制台输出:

09:21:54.3952161 - null - ChangeState(Disconnected, Connecting)
[28/05/2015 10:21:54]: Disconnected =>  Connecting
[28/05/2015 10:21:56]: Connecting =>  Disconnected
09:21:56.8448452 - null - Disconnected
09:21:56.8458461 - null - Transport.Dispose()
09:21:56.8468465 - null - Closed

这是我的中心代码:

public class ChatHub : Hub

    public void SendMessage(string name, string message)
    
        Clients.All.ReceiveMessage(name, message);
    

【问题讨论】:

尝试turn on SignalR tracing on server。希望 SignalR 将记录错误... 【参考方案1】:

结果证明这是一个微不足道的错误,但错误消息是如此无用,我相信其他人也会被同样的问题难住。集线器的名称是错误的。我应该使用“ChatHub”时使用了“Chat”。

如果异常是 404 或“未找到集线器”或类似情况,这将是一个简单的修复,而不是浪费几个小时!

【讨论】:

如果名称正确但 Hub 类不公开,也会发生这种情况。 搞了半天才发现是CreateHubProxy中的错字导致的!我讨厌后期绑定和非强类型。 感谢这一天 @MichaelTiller - 非常感谢,这就是我的问题。 @Darren 干得好!请将此标记为最佳答案。【参考方案2】:

@Michael Tiller 在@Darren 的回答中的评论原来是我的问题的解决方案,所以我认为将其作为自己的答案是公平的:

将 Hub 类更改为 public 解决了我的问题。我跟着一个例子,错过了说创建一个继承自 Hub 的 PUBLIC 类的文本,并且在 Visual Studio 中添加一个新类时,默认情况下它会将其创建为

class TestHub


...技术上是internal(参见here)。更仔细的阅读本可以防止这种情况发生,但万一其他人像我一样太着急了...... :)

【讨论】:

【参考方案3】:

真正的问题已解决我认为重要的是要意识到 SignalR 服务器返回状态 500(内部服务器错误)(确实不是非常有用的错误)是安全功能

如果您需要有关服务器错误的更多信息,您可以执行以下操作:

1) Enable tracing on server

和\或

2) 启用向客户端发送详细的异常消息(不要在生产中这样做!):

SignalR 1.x: RouteTable.Routes.MapHubs(new HubConfiguration EnableDetailedErrors = true );

SignalR 2.x

public void Configuration(IAppBuilder app)

        var hubConfiguration = new HubConfiguration
        
#if DEBUG
            EnableDetailedErrors = true
#else
            EnableDetailedErrors = false
#endif
        ;

        app.MapSignalR(hubConfiguration);

【讨论】:

【参考方案4】:

我犯了类似的小错误,花了几个小时才弄明白。

[HubName("Hostsync")] // Missed to add this attribute in Hub of SignalR Self Host
public class ChatHub : Hub



但我试图通过在客户端中定义代理名称来连接。

HostProxyName = "Hostsync";

只要确保没有此类错误即可。因为在连接建立期间您不会得到确切的详细异常。

以下链接帮助我解决了一些问题

堆栈溢出Question Answer Link

希望这会有所帮助。,

【讨论】:

【参考方案5】:

我有同样的问题。我发现 SignalR Jquery 扩展版本比引用的 SignalR 库旧。我更正了脚本版本并解决了问题。如果您最近将 SignalR 升级到更新版本,您可能会遇到和我一样的问题。

【讨论】:

以上是关于从 SignalR .NET 客户端连接到工作集线器时出现 HttpClientException的主要内容,如果未能解决你的问题,请参考以下文章

如何编写 Netty 客户端以连接到 Signalr 集线器?

获取连接到 SignalR 集线器的侦听器和客户端的数量

SignalR 控制台应用程序示例

SignalR JavaScript客户端API调用连接

SignalR 2.2 客户端未收到任何消息

在信号器集线器类上设置 [Authorize] 属性仅在连接到集线器时有效,而不是在集线器上的每个方法之前(ASP.NET Core 2.2)