首页 > 解决方案 > SignalR 的新手,有没有办法在用户执行操作时向其他人广播,而不仅仅是在他们开始和完成时?

问题描述

所以我想要做的,我在这里做了一个小示例项目,是当用户编辑表格中的单元格时,该单元格对该页面上的其他所有人禁用。都好。在这里我进行了设置,以便当用户进入一个单元格时,它会对其他人禁用,并且在模糊/退出单元格时,它会清除。现在的问题是,如果一个人在牢房中,它会在其他人的屏幕上禁用。但是,如果有人刷新或新用户进入页面,它不会被禁用,即使主用户仍在该单元格中。SignalR 有没有办法知道某人在使用特定单元时正在使用它,而不仅仅是在他进入/退出单元时?

C#代码:

    public class ChatHub : Hub
    {
        public void Send(string name, string message, bool boolean)
        {
            // Call the broadcastMessage method to update clients.
            Clients.Others.broadcastMessage(name, message, boolean);
        }
    }

HTML 代码:

<table id="table">
    <thead>
        <tr>
            <th>HeaderOne</th>
            <th>HeaderTwo</th>
            <th>HeaderThree</th>
        </tr>
    </thead>
    <tbody>
        @for(int i = 0; i < 3; i++)
        {
        <tr>
            <td><input class="tdInput" /></td>
            <td><input class="tdInput" /></td>
            <td><input class="tdInput" /></td>
        </tr>
        }
    </tbody>
</table>

Javascript代码:

        $(function () {
            var conn = $.connection.chatHub;

            conn.client.broadcastMessage = function (col, row, boolean) {
                var cell = $("#table tr:eq(" + row + ") td:eq(" + col + ")");
                cell.find("input").prop('disabled', boolean);
            };

            $.connection.hub.start().done(function () {
                $(".tdInput").on('focus', function () {
                    var col = $(this).parent().index();
                    var row = $(this).closest('tr').index() + 1;
                    conn.server.send(col, row, true);
                });
                $(".tdInput").on('blur', function () {
                    var col = $(this).parent().index();
                    var row = $(this).closest('tr').index() + 1;
                    conn.server.send(col, row, false);
                });
            });
        });

这是 Christoph 评论中选项 #2 的简单实现:

在 connection.hub.start() 中,添加:

conn.server.refresh();

在 JS 中:

conn.client.resendStatus = function () {
    if ($('input:focus').length > 0) {
        var focused = $(":focus");
        var col = focused.parent().index();
        var row = focused.closest('tr').index() + 1;
        conn.server.send(col, row, true);
    }
};

在集线器中:

public void Refresh()
{
    Clients.Others.resendStatus();
}

标签: javascriptc#asp.net-mvcsignalr

解决方案


在我看来,有两种可能的解决方案:

  1. 跟踪服务器上所有锁定的单元格,并在用户加载页面时将它们标记为已锁定。
  2. 加载页面后,向所有客户端发送广播,告诉他们重新发送当前的编辑状态。

第二个选项更容易处理,因为您不需要任何状态跟踪,尤其是不需要超时。但是,您将在加载页面后有很短的时间,在此期间其他人编辑的单元格会暂时解锁。


推荐阅读