【问题标题】:SignalR connection 400 error (Bad Request)SignalR 连接 400 错误(错误请求)
【发布时间】:2018-01-15 12:57:03
【问题描述】:

我正在尝试构建一个 SignalR 概念证明,其中涉及两个应用程序;一个是 Web 单页应用程序,另一个是服务器端 RESTful Web api。使用的技术/框架是 ReactJs、ASP.NET Web API 2(.NET Framework 4.6,不是 .NET Framework Core)和 SignalR。

网络 API

这就是我在服务器应用程序中连接 SignalR 的方式。当应用程序启动时,我将 SignalR 映射到应用程序管道...

public static void ConfigureSignarlR(IAppBuilder app)
{            
    app.MapSignalR<ChatConnection>("/signalr", new Microsoft.AspNet.SignalR.HubConfiguration
    {
        EnableDetailedErrors = true
    });                
}

ChatConnection 类是 PersistentConnection 的一个实现,没有什么特别的...

    public class ChatConnection : PersistentConnection
    {
        protected override Task OnReceived(IRequest request, string connectionId, string data)
        {
            return base.OnReceived(request, connectionId, data);
        }

        protected override Task OnConnected(IRequest request, string connectionId)
        {
            return base.OnConnected(request, connectionId);
        }

        public override Task ProcessRequest(HostContext context)
        {
            return base.ProcessRequest(context);
        }
    }

然后我有一个非常简单的集线器...

public class ChatHub : Hub
{
    public void Send(string name, string message)
    {
        Clients.All.broadcastMessage(name, message);
    }
}

客户端应用

对于客户端应用程序,我使用@aspnet/signalr-client npm 包...这是我创建和启动连接的方式...

initialize = () => {
    const hubCon = new HubConnection("http://api.domain/signalr");
    hubCon.start()
           .then(() => console.log("Connection established..."))
           .catch(err => console.log(err))
}

注意事项

  1. API 和客户端应用程序都托管在同一个本地 IIS 服务器上,但主机名不同(使用主机文件)

  2. 使用浏览器导航到http://api.domain/signalr/hubs 时,当消息Protocol error: Unknown transport. 之后出现消息时,我收到400(错误请求)响应

  3. 尝试从客户端应用程序连接时,我收到相同的错误消息

  4. ProcessRequest 方法是调试 ChatConnection 类时唯一受到影响的方法

问题

我错过了什么?或者我怎样才能让这个 PoC 工作?

这个问题非常广泛,因为我真的不知道这里发生了什么

【问题讨论】:

    标签: reactjs asp.net-web-api signalr


    【解决方案1】:

    经过一番挖掘和阅读 SignalR 文档后,我意识到我做错了一切。基本上,SignalR 实现了两种不同的连接模式:

    • 集线器:建立在持久连接 API 之上的高级 API
    • 持久连接

    客户端无法使用 Hub 代理与持久连接端点进行通信(或者至少不是我这样做的方式)。所以,我所做的是:

    1. 保留 PersistentConnection 但重写了 OnReceived 方法,以便它可以向所有客户端广播

      protected override async Task OnReceived(IRequest request, string connectionId, string data)
      {
          await Connection.BroadCast("message to broadcast");
      }
      
    2. 删除了“signalr\hubs”脚本引用,因为它不需要

    3. 在启动时注册连接(服务器端)

      app.MapSignalR&lt;ChatConnection&gt;("/chat");

    4. 最后,在客户端,初始化连接并注册所有必要的回调

      this.connection = window.$.connection(process.env.REACT_APP_API_BASE_URI + "/chat");
      this.connection.logging = true;
      
      this.connection.received((data) => {
          console.log("Received some data:")
          console.log(data)
      });
      
      
      this.connection.start(() => {
          console.log("Connection opened")
          console.log("connectionId = " + this.connection.id)
      });
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 2017-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-05
      相关资源
      最近更新 更多