较旧的异步消息会覆盖较新的异步消息

时间:2013-10-28 10:13:56

标签: asp.net signalr keyboard-events

我们正在SignalR开发一个文档协作工具,多个用户可以在其中更新一个WYSIWYG表单。

我们正在努力让应用程序使用KeyUp方法将更改发送回服务器。这会导致系统覆盖用户在发送消息后第一次按键时写入的内容。

有没有解决这个问题?

目前我尝试设置2秒超时但这会延迟所有更新,而不仅仅是“作家”页面。

public class ChatHub : Hub
{
    public ChatHub()
    {

    }

    public void Send(int id,string message)
    {
        // Call the broadcastMessage method to update clients.     
        Clients.All.broadcastMessage(id,message); //id is for the document id where to update the content
    }

}

和客户:

$(function () {

        // Declare a proxy to reference the hub. 
        var chat = $.connection.chatHub;
        //console.log("Declare a proxy to reference the hub."); 

        // Create a function that the hub can call to broadcast messages.
        chat.client.broadcastMessage = function (id, message) {

            var encodedValue = $('<div />').text(id).html();


            // Add the message to the page.  

            if (encodedValue == $('#hdnDocId').val()) {

                $('#DiaplayMsg').text(message);
                tinyMCE.activeEditor.setContent("");
                tinyMCE.get('txtContent').execCommand('insertHTML', false, message); //!!!


            }
        };

        // Start the connection.

        $.connection.hub.start().done(function (e) {
            //console.log("Start the connection.");

            if ($('#hdnDocId').val() != '') {

                tinyMCE.activeEditor.onKeyUp.add(function (ed, e) {
                    var elelist = $(tinyMCE.activeEditor.getBody()).text();


                    var content = tinyMCE.get('txtContent').getContent();


                    function Chat() {

                        var content = tinyMCE.get('txtContent').getContent();

        chat.server.send($('#hdnDocId').val(), content); //send a push to server

                    }

                    typewatch(Chat, 2000);
                });
            }
        });

    });
    var typewatch = function () {
        var timer = 0;
        return function (Chat, ms) {
            clearTimeout(timer);
            timer = setTimeout(Chat, ms);
        }
    } ();
</script>

您好,这是客户端KeyUp代码的更新。它似乎工作,但我想你的意见。我使用了一个全局变量来存储超时,见下文:

<script type="text/javascript">
    $(function () {

        // Declare a proxy to reference the hub. 
        var chat = $.connection.chatHub;
        //console.log("Declare a proxy to reference the hub.");          
        // Create a function that the hub can call to broadcast messages.
        chat.client.broadcastMessage = function (id, message) {

            var encodedValue = $('<div />').text(id).html();

            var currenttime = new Date().getTime() / 1000 - 2
            if (typeof window.istyping == 'undefined') {
                window.istyping = 0;
            }

            if (encodedValue == $('#hdnDocId').val() && window.istyping == 0 && window.istyping < currenttime) {

                function Update() {
                    $('#DiaplayMsg').text(message);
                    tinyMCE.activeEditor.setContent("");
                    tinyMCE.get('txtContent').execCommand('insertHTML', false, message); //!!!
                    //                                        tinyMCE.get('txtContent').setContent(message);
                    window.istyping = 0
                }
                Update();
            }
        };

        // Start the connection.

        $.connection.hub.start().done(function (e) {
            //console.log("Start the connection.");

            if ($('#hdnDocId').val() != '') {

                tinyMCE.activeEditor.onKeyUp.add(function (ed, e) {
                    var elelist = $(tinyMCE.activeEditor.getBody()).text();

                    var content = tinyMCE.get('txtContent').getContent();

                    function Chat() {
                        //alert("Call");
                        var content = tinyMCE.get('txtContent').getContent();
                        chat.server.send($('#hdnDocId').val(), content);
                        window.istyping = new Date().getTime() / 1000;
                    }
                    Chat();

                });
            }
        });

    });
    var typewatch = function () {
        var timer = 0;
        return function (Chat, ms) {
            clearTimeout(timer);
            timer = setTimeout(Chat, ms);
        }
    } ();

谢谢, 罗伯特。

2 个答案:

答案 0 :(得分:0)

  

有没有解决这个问题?

是的,不是将整个文档发送到服务器,而是记录段落,表格单元格等元素。您可以在用户停止键入一段时间后,或者当焦点丢失时同步这些

否则为消息添加一些递增计数器,因此较旧的返回值不会覆盖较早到达的较新值。

但是你基本上要求我们解决有关合作文档编辑的一个非平凡的问题。 试过了什么?

答案 1 :(得分:0)

“这会导致系统覆盖用户写的内容”

那是因为这段代码没有做任何合并更改的努力。它只是盲目地覆盖那里的任何东西。

tinyMCE.activeEditor.setContent("");
tinyMCE.get('txtContent').execCommand('insertHTML', false, message);

正如@CodeCaster所暗示的那样,您需要在发送的消息中更加精确 - 来回传递特定的更改而不是重新发送整个文档 - 以便在接收方可以小心地合并更改