Javascript 对于SignalR来说,是否有一种方式可以在用户执行操作时向其他人广播,而不仅仅是在他们开始和结束时?

Javascript 对于SignalR来说,是否有一种方式可以在用户执行操作时向其他人广播,而不仅仅是在他们开始和结束时?,javascript,c#,asp.net-mvc,signalr,Javascript,C#,Asp.net Mvc,Signalr,所以我想做的是,我在这里做了一个小的示例项目,当用户在编辑表中的单元格时,该单元格会禁用该页面上的其他所有单元格。一切都好。在这里,我将其设置为,当用户进入一个单元格时,它将为其他所有人禁用,当模糊/退出单元格时,它将清除。现在的问题是,如果一个人在手机中,它会在其他人的屏幕上禁用。但是,如果有人刷新或有新用户进入该页面,则该页面不会被禁用,即使主用户仍在该单元格中。信号员有没有办法知道有人在使用某个特定的手机,而不仅仅是在他进入/退出手机时 C#代码: HTML代码: <table id

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

C#代码:

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>
下面是Christoph评论中选项2的一个简单实现:

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

在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();
}

我认为有两种可能的解决办法:

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

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

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

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

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

    您可以添加setTimeout,这将每秒发送一次锁定/状态,直到用户位于单元格中

    $(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 () {
            var flag=false;
            $(".tdInput").on('focus', function () {
                flag=true;
                while(flag)
                {
                    setTimeout(function(){
                        var col = $(this).parent().index();
                        var row = $(this).closest('tr').index() + 1;
                        conn.server.send(col, row, true);
                    },1000);
                }
            });
    
            $(".tdInput").on('blur', function () {
                flag=false;
                var col = $(this).parent().index();
                var row = $(this).closest('tr').index() + 1;
                conn.server.send(col, row, false);
            });
        });
    });
    

    您可以添加setTimeout,这将每秒发送一次锁/状态,直到用户在单元格中

    $(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 () {
            var flag=false;
            $(".tdInput").on('focus', function () {
                flag=true;
                while(flag)
                {
                    setTimeout(function(){
                        var col = $(this).parent().index();
                        var row = $(this).closest('tr').index() + 1;
                        conn.server.send(col, row, true);
                    },1000);
                }
            });
    
            $(".tdInput").on('blur', function () {
                flag=false;
                var col = $(this).parent().index();
                var row = $(this).closest('tr').index() + 1;
                conn.server.send(col, row, false);
            });
        });
    });
    

    非常感谢。这帮了大忙。我已经用代码编辑了我的主要帖子,我认为代码实现了第2个。我还有一个问题,程序工作,如果用户1进入一个单元格,它在用户2的屏幕上被禁用。当用户1退出时,它将在用户2的屏幕中清除。但是,如果用户1进入屏幕,然后刷新或关闭浏览器,则在用户2的屏幕上会永久禁用浏览器,直到刷新为止。我不知道该怎么解决这个问题。我应该实现Garth的想法,还是应该在退出页面时清除所有单元格?在使用beforeunload离开页面之前,我只是对当前聚焦的元素进行了手动模糊。我不知道这是不是一个好办法!事实上,这并不是唯一可能发生这种情况的情况。如果用户失去internet连接,您将获得类似的效果,但卸载前的处理不会有帮助。相反,我建议在信号集线器中处理断开连接事件:。在客户端断开连接时,您可以通知所有客户端释放所有单元格并重新提交其焦点,以便所有单元格都恢复到其应处于的状态。在重新连接时,同样的事情可能是有意义的,但你应该处理冲突,以防另一个客户集中在同一个单元。我感觉很糟糕,我问了很多问题,但另一件事情出现了,我不知道如何修复。如果我在我的主项目中同时更改了很多内容,那么有时需要花费一些时间来加载。因此,如果用户1快速连续地一次更改10个单元格,并且在ajax运行时,用户2刷新页面,那么用户2的数据将一直很旧,直到再次刷新为止,因为我认为控制器操作在ajax更新数据库之前运行。如果用户1在ajax调用期间刷新自己,也会发生这种情况。谢谢!这帮了大忙。我已经用代码编辑了我的主要帖子,我认为代码实现了第2个。我还有一个问题,程序工作,如果用户1进入一个单元格,它在用户2的屏幕上被禁用。当用户1退出时,它将在用户2的屏幕中清除。但是,如果用户1进入屏幕,然后刷新或关闭浏览器,则在用户2的屏幕上会永久禁用浏览器,直到刷新为止。我不知道该怎么解决这个问题。我应该实现Garth的想法,还是应该在退出页面时清除所有单元格?在使用beforeunload离开页面之前,我只是对当前聚焦的元素进行了手动模糊。我不知道这是不是一个好办法!事实上,这并不是唯一可能发生这种情况的情况。如果用户失去internet连接,您将获得类似的效果,但卸载前的处理不会有帮助。相反,我建议在信号集线器中处理断开连接事件:。在客户端断开连接时,您可以通知所有客户端释放所有单元格并重新提交其焦点,以便所有单元格都恢复到其应处于的状态。在重新连接时,同样的事情可能是有意义的,但你应该处理冲突,以防另一个客户集中在同一个单元。我感觉很糟糕,我问了很多问题,但另一件事情出现了,我不知道如何修复。如果我在我的主项目中同时更改了很多内容,那么有时需要花费一些时间来加载。因此,如果用户1快速连续地一次更改10个单元格,并且在ajax运行时,用户2刷新页面,那么用户2的数据将一直很旧,直到再次刷新为止,因为我认为控制器操作在ajax更新数据库之前运行。如果用户1在ajax调用期间刷新自己,也会发生这种情况。但是,这会不会给服务器带来比必要时更大的负载?它将每秒持续通知所有其他客户端。只要没有人重新加载页面,这似乎是一个很大的开销。是的,唯一的其他选择是仅由您选择,存储在服务器上:),但是,这不会使服务器上的负载超过必要的负载吗?它将持续通知所有其他人
    public void Refresh()
    {
        Clients.Others.resendStatus();
    }
    
    $(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 () {
            var flag=false;
            $(".tdInput").on('focus', function () {
                flag=true;
                while(flag)
                {
                    setTimeout(function(){
                        var col = $(this).parent().index();
                        var row = $(this).closest('tr').index() + 1;
                        conn.server.send(col, row, true);
                    },1000);
                }
            });
    
            $(".tdInput").on('blur', function () {
                flag=false;
                var col = $(this).parent().index();
                var row = $(this).closest('tr').index() + 1;
                conn.server.send(col, row, false);
            });
        });
    });