14

我在 Angular 应用程序中使用 SignalR。当我在 Angular 中销毁组件时,我还想停止与集线器的连接。我使用命令:

this.hubConnection.stop();

但我在 Chrome 控制台中收到错误: Websocket 已关闭,状态码为:1006

在边缘:错误错误:未捕获(承诺):错误:由于连接关闭而取消调用。错误:由于连接关闭而取消调用。

它实际上有效并且连接已停止,但我想知道为什么会出现错误。

这就是我启动集线器的方式:

this.hubConnection = new HubConnectionBuilder()
      .withUrl("/matchHub")
      .build();

    this.hubConnection.on("MatchUpdate", (match: Match) => {
      // some magic
    })

    this.hubConnection
      .start()
      .then(() => {
        this.hubConnection.invoke("SendUpdates");
      });

编辑

我终于找到问题了。它是由来自 Mongo 的更改流引起的。如果我从 SendUpdates() 方法中删除代码,则会触发 OnDisconnected。

    public class MatchHub : Hub
    {
    private readonly IMatchManager matchManager;

    public MatchHub(IMatchManager matchManager)
    {
        this.matchManager = matchManager;
    }

    public async Task SendUpdates() {
        using (var changeStream = matchManager.GetChangeStream()) {
            while (changeStream.MoveNext()) {
                var changeStreamDocument = changeStream.Current.FullDocument;
                if (changeStreamDocument == null) {
                    changeStreamDocument = BsonSerializer.Deserialize<Match>(changeStream.Current.DocumentKey);
                }
                await Clients.Caller.SendAsync("MatchUpdate", changeStreamDocument);
            }
        }
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        await base.OnDisconnectedAsync(exception);
    }
}

来自管理器的方法 GetChangeStream。

        ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
        var watch =  mongoDb.Matches.Watch(options).ToEnumerable().GetEnumerator();
        return watch;

但我不知道如何解决它。

4

2 回答 2

1

这可能有很多原因,但我认为很可能是这个:

我认为这是因为服务器如何处理连接/断开的事件。我不能肯定地说,但连接关闭也需要在服务器上正确处理代码。尝试覆盖服务器上内置的 On Connected /Disconnected 方法并查看。我的假设只是您正在关闭它,但服务器没有正确关闭,因此没有转发正确的关闭响应。

作为评论发现:get the reason why websockets closed with close code 1006

您不需要更改连接/断开连接,因为 evrything 工作正常。但作为答案,这是最有可能的。

于 2019-01-01T20:30:41.130 回答
0

它会引发错误,因为回调没有正确清除。

它是由 websocket 的返回数据引起的。

通常它应该像

在此处输入图像描述

但是,由于某种原因,它可能会返回类似

在此处输入图像描述

最后的回应分成两部分

这导致了这个问题。

我认为没有办法在不更改源代码的情况下绕过它。

我也在 github repo 上报告了这个

事实证明,我可以利用调用响应来通知客户端停止集线器。所以它不会触发赛车问题。

于 2019-01-24T21:12:18.977 回答