1

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

我们正在努力让应用程序使用 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);
        }
    } ();

谢谢,罗伯托。

4

2 回答 2

0

有没有办法解决这个问题?

是的,不是将整个文档发送到服务器,而是将文档元素(如段落、表格单元格等)发送到服务器。您可以在用户停止输入一段时间后或失去焦点时同步这些内容。

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

但是您基本上是在要求我们解决有关协作文档编辑的重要问题。你试过什么

于 2013-10-29T09:45:19.727 回答
0

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

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

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

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

于 2013-10-29T14:58:30.233 回答