【问题标题】:SignalR not firing OnDisconnectedSignalR 未触发 OnDisconnected
【发布时间】:2017-09-15 09:06:54
【问题描述】:

问题: SignalR 没有在我的网络服务器上触发 OnDisconnected。这很简单,但不是射击。我试过了:

  • 关闭浏览器窗口
  • 导航离开
  • 重新加载
  • 从客户端触发 SignalR 连接上的 stop()。

public override Task OnDisconnected(bool stopCalled) {
    LogUtil.LogInfo("Disconn");
    return base.OnDisconnected(stopCalled);
}

我正在使用 SignalR 2.2.0.0,OnConnected 工作正常。
我已尝试建议最后一次调用客户端以确保连接已启动并正在运行。
我搜索了所有论坛、SO、GIT 等,但没有解决我的问题。

【问题讨论】:

  • 我有相同的版本,但断开连接大约需要 40 秒。 (该事件会在 40 秒后触发。)原因与在网络速度较慢的情况下尝试重新连接到用户的功能有关 - 不过我记不太清了。关闭浏览器后是否等待了足够的时间?顺便说一句,您使用的是哪个浏览器?
  • 我已经等了 30 分钟。 Chrome 版本 60.0.3112.113
  • 我也有 chrome 60。关闭选项卡,重新加载它或在客户端调用停止应该足够了。你能发布 hub.connect 和 hub.stop 相关代码吗?另外,尝试在客户端上添加stateChanged 事件并查看其日志,以防发生奇怪的事情。
  • SignalR 状态从:断开连接到:正在连接 -> SignalR 状态从:连接到:连接 -> onmessage { "msg": "Users online: 2" } -> -> --Pressing重新加载 -> SignalR 状态从:连接到:断开连接 -> SignalR 状态从:断开连接到:正在连接 -> SignalR 状态从:连接到:连接
  • 嗯,正如预期的那样......所以当状态变为断开连接时它不会触发服务器事件吗?

标签: c# asp.net signalr


【解决方案1】:

我也遇到了这个问题,我不得不使用 LongPolling。我也找不到任何当前断开/重新连接 javascript 代码的示例。

这是我的代码(为了完整性,不包括伪劣的 html):

<hr />

<style>
 table { table-layout: fixed; }
 table th, table td { overflow: hidden; }
</style>

<div id="logs">
    <table id="logTable" class="table">
        <thead>
            <tr>
                <th style="width: 20%">Time</th>
                <th style="width: 5%">Level</th>
                <th>Message</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="/lib/signalr-clientES5-1.0.0-alpha2-final.js" type="text/javascript"></script>
<script type="text/javascript">

    // global refs
    var transportType;
    var logger;
    var loggingHub;
    var loggingConnection;

    function prependLogRow(logEvent) {
        var d = new Date(logEvent.timeStamp); //.ToString("dd/MM H:mm:ss");
        var m = logEvent.message;
        var s = "<tr><td>" + d + "</td><td>" + logEvent.level + "</td><td>" + m + "</td></tr>";
        $("#logTable tbody").prepend(s);

        var rowCount = $('#logTable tr').length;
        if (rowCount > 500) {
            $("#logTable").find("tr:gt(250)").remove();
        }
    };

    function createLogEvent(message) {
        var logEvent = {};
        logEvent.timeStamp = new Date();
        logEvent.level = 'Info';
        logEvent.message = message;
        return logEvent;
    };

    function bindEvents(logger) {

        logger.connection.onclose = (e) => {
            var logEvent = createLogEvent('Logger disconnected. Retrying...');
            prependLogRow(logEvent);
            setTimeout(function () 
            {
                transportType = signalR.TransportType.LongPolling; //;WebSockets
                logger = new signalR.ConsoleLogger(signalR.LogLevel.Trace);
                loggingHub = new signalR.HttpConnection(`https://${document.location.host}/signalr`, { transport: transportType, logger: logger });
                loggingConnection = new signalR.HubConnection(loggingHub, logger);
                bindEvents(loggingConnection);
                var logEvent = createLogEvent('Logger reconnected.');
                prependLogRow(logEvent);
            }, 1000); // Restart connection after a second.
        };

        logger.on('Log', (logEvent) => {
            prependLogRow(logEvent);
        });

        logger.start().catch(err => {
            console.log('connection error');
        });
    };

    $(document).ready(function () {

        transportType = signalR.TransportType.LongPolling; //;WebSockets
        logger = new signalR.ConsoleLogger(signalR.LogLevel.Trace);
        loggingHub = new signalR.HttpConnection(`https://${document.location.host}/signalr`, { transport: transportType, logger: logger });
        loggingConnection = new signalR.HubConnection(loggingHub, logger);

        bindEvents(loggingConnection);

        var logEvent = createLogEvent('Logger loaded. Please wait...');
        prependLogRow(logEvent);
    })
</script>

这段代码感觉不对,但这是我唯一可以可靠工作的迭代。

【讨论】:

    【解决方案2】:

    我还遇到了登录 OnDisconnect 无法正常工作的问题。像你一样,我认为 OnDisconnect 方法没有被调用。

    但事实证明,我假设 HttpContext.Current 可用。 (我的记录器使用它从会话中提取一些状态信息。)当您考虑它时,期望当前上下文是没有意义的。毕竟,您正在断开连接!为 HttpContext.Current 引发了一个空指针异常,但我看不到它。

    一旦我删除了对 HttpContext.Current 的依赖,我就能够记录断开连接并发送警报电子邮件。

    【讨论】:

      【解决方案3】:

      在我的例子中,我至少需要一个 chat.client.broadcast 方法才能使其工作......否则,它会触发除 OnDisconnected 方法之外的任何其他事件。

      【讨论】:

        【解决方案4】:

        就我而言,我有一个仅用于调用服务器方法的集线器。

        当我为 javascript 代理客户端订阅至少一个服务器集线器事件时,OnDisconnected 方法开始触发。

        hubProxy.on('myEvent', myHandler);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多