SignalR在Chrome浏览器中的更新不正常。

7

我创建了一个带有SignalR通知的ASP MVC 4应用程序。我在本地以Debug模式运行它,并通过IIS发布在服务器上运行。当使用Internet Explorer 11时,它基本按预期工作(稍后会解释原因):

HTML1300: Navigation occurred.
File: AllChanges
SignalR: Window unloading, stopping the connection.
SignalR: Stopping connection.
SignalR: Stopping forever frame.
SignalR: Fired ajax abort async = false.
SignalR: Stopping the monitoring of the keep alive.
JQMIGRATE: Migrate is installed, version 3.0.0
SignalR: Client subscribed to hub 'prismhub'.
SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22prismhub%22%7D%5D'.
SignalR: serverSentEvents transport starting.
SignalR: This browser doesn't support SSE.
SignalR: serverSentEvents transport failed to connect. Attempting to fall back.
SignalR: foreverFrame transport starting.
SignalR: Binding to iframe's load event.
SignalR: Iframe transport started.
SignalR: foreverFrame transport connected. Initiating start request.
SignalR: The start request succeeded. Transitioning to the connected state.
SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
Connected to signalR hub
SignalR: foreverFrame transport timed out when trying to connect.
**SignalR: Triggering client hub event 'sendUpdatedChange' on hub 'prismHub'.**

Chrome浏览器似乎无法显示通知。在日志中,我可以看到SignalR正在推送通知:

SignalR: Window unloading, stopping the connection.
SignalR: Stopping connection.
SignalR: EventSource calling close().
SignalR: Fired ajax abort async = false.
SignalR: Stopping the monitoring of the keep alive.
JQMIGRATE: Migrate is installed, version 3.0.0
SignalR: Client subscribed to hub 'prismhub'.
SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22prismhub%22%7D%5D'.
SignalR: serverSentEvents transport starting.
SignalR: Attempting to connect to SSE endpoint 'http://localhost:61159/signalr/connect?transport=serverSentEvents&clientPro…FNE6BKzqphux4&connectionData=%5B%7B%22name%22%3A%22prismhub%22%7D%5D&tid=9'.
SignalR: EventSource connected.
SignalR: serverSentEvents transport connected. Initiating start request.
SignalR: The start request succeeded. Transitioning to the connected state.
SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
Connected to signalR hub
**SignalR: Triggering client hub event 'sendUpdatedChange' on hub 'prismHub'.
SignalR: Triggering client hub event 'sendUpdatedChange' on hub 'prismHub'.
SignalR: Triggering client hub event 'sendUpdatedChange' on hub 'prismHub'.**

但是在我的观察中,数据没有发生变化(就像在Internet Explorer中一样)。这个问题偶尔会出现在IE中。此外,刷新页面似乎会破坏中心连接。从IE控制台:

HTML1300: Navigation occurred.
File: AllChanges
JQMIGRATE: Migrate is installed, version 3.0.0
SignalR: Client subscribed to hub 'prismhub'.
SignalR: Negotiating with '/signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22prismhub%22%7D%5D'.
SignalR: serverSentEvents transport starting.
SignalR: This browser doesn't support SSE.
SignalR: serverSentEvents transport failed to connect. Attempting to fall back.
SignalR: foreverFrame transport starting.
SignalR: Binding to iframe's load event.
SignalR: Iframe transport started.
SignalR: foreverFrame transport connected. Initiating start request.
SignalR: The start request succeeded. Transitioning to the connected state.
SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
Connected to signalR hub
SignalR: foreverFrame transport timed out when trying to connect.

值得注意的是,这些请求会进行ajax调用到控制器,然后使用linq查询访问数据库,返回数据列表:
视图JS
$(document).ready(function () {
    FetchChanges();
    notifications.client.sendUpdatedChange = function () { FetchChanges(); };
}

function FetchChanges() {
    var model = $('#divChanges');
    $.ajax({
        url: '/Changes/AllChangesItems',
        contentType: 'application/html ; charset:utf-8',
        type: 'GET',
        dataType: 'html',
    })
    .done(function (result) {
        model.empty().append(result);
    })
}

控制器操作

public ActionResult AllChangesItems()
{
    var username = CurrentUser().UserName;
    var changes = db.Changes;

    List<ChangeListingViewModel> vm = new List<ChangeListingViewModel>();
    foreach (var c in changes)
    {
        vm.Add(new ChangeListingViewModel(c));
    }

    return PartialView("_ActiveItems", vm.ToList());
}

ChangeListingViewModel 包含两个 linq 查询,用于获取子行(如果相关,可以提供代码):

然而,在 IE 和 Chrome 中,“更简单”的查询似乎可以正常工作,即推送通知触发 JS 函数更新视图:

public void PinChange(int id)
{
    CurrentUserDetails().User.PinnedChanges.Add(db.Changes.Find(id));
    db.SaveChanges();
    PrismHub.NotifyPinnedChange();
}

我的第一反应是可能发生了某种超时,但我不确定为什么这在不同的浏览器之间会有差异。非常感谢任何建议。

编辑:已更新Hub信息 编辑2:将hub方法更新为与其他片段一致的方法。

下面是我的Hub类代码片段:

Hub

[HubName("prismHub")]
public class PrismHub : Hub
{
    private static IHubContext context = GlobalHost.ConnectionManager.GetHubContext<PrismHub>();

    [HubMethodName("notifyUpdatedChange")]
    public static void NotifyUpdatedChange()
    {
        context.Clients.All.sendUpdatedChange();            
    }
}

2
你能展示一下服务器上的hub是如何实现的吗?请确保在hub类中添加一个hub属性。[HubName("SomeHub")] public class SomeHub: Hub {} - Omar Zaarour
1个回答

3

偶然发现了解决方案。在搜索了几周后,我遇到了这篇文章:signalr客户端的Hub事件没有在jquery的.ready()方法中被触发

通过处理视图中的以下JS代码,解决了这个问题:

$(document).ready(function () {
    FetchChanges();
    notifications.client.sendUpdatedChange = function () { FetchChanges(); };
}

将SignalR函数映射移出$(document).ready()可以解决此问题:
$(document).ready(function () {
    FetchChanges();    
}
notifications.client.sendUpdatedChange = function () { FetchChanges(); };

我还没有发现为什么会出现这个问题,但很高兴找到了解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接