Javascript 动态防止Socket.io超时?

Javascript 动态防止Socket.io超时?,javascript,node.js,d3.js,socket.io,Javascript,Node.js,D3.js,Socket.io,我正试图防止我的Socket.io客户端由于心跳超时而断开与服务器的连接,因为我的客户端在操作DOM上花费了太多时间 一般来说,Socket.io超时对于我的应用程序来说是非常好的。只有一个实例,客户机可能希望在其中生成他们正在使用的数据表。数据的大小是可变的,这取决于客户端使用的数据集,因此数据可能很小(这不是问题),也可能很大。我关注的是数据太大,以至于Socket.io心跳超时的情况 由于数据长度可变,并且是在客户机/服务器连接初始化后选择的,因此我需要能够动态地操纵超时允许的时间量。换句

我正试图防止我的Socket.io客户端由于心跳超时而断开与服务器的连接,因为我的客户端在操作DOM上花费了太多时间

一般来说,Socket.io超时对于我的应用程序来说是非常好的。只有一个实例,客户机可能希望在其中生成他们正在使用的数据表。数据的大小是可变的,这取决于客户端使用的数据集,因此数据可能很小(这不是问题),也可能很大。我关注的是数据太大,以至于Socket.io心跳超时的情况

由于数据长度可变,并且是在客户机/服务器连接初始化后选择的,因此我需要能够动态地操纵超时允许的时间量。换句话说,除了这个特定的实例之外,超时一般都是正常的,因此我想根据DOM操作的进行方式增加允许超时的时间量,并在DOM操作完成后将其重置为正常超时

这里需要补充的一点信息是,我的服务器的断开连接代码杀死了为处理一些繁重的数据计算而生成的Python进程。此过程与特定客户机相关联。因此,如果客户机/服务器通信中断,那么客户机与这个Python进程的通信也会中断,这意味着如果客户机无法保持与服务器的连接,那么它实际上是无用的。这意味着简单的“重新连接”是不够的(除非我可以在服务器决定终止Python进程之前重新连接回相同的Socket.io文件室/会话)

有人知道如何正确地动态操作Socket.io心跳超时吗?或者,在长时间的DOM操作过程中,我是否可以首先防止超时?如果有一种方法可以在不挂断客户端并在生成表时保持其交互性的情况下执行此DOM操作,则会获得额外的好处

代码/浏览器版本:

  • Node.js:8.16.2(我知道这很旧,但我们依赖的是一个与Node.js的较新版本不兼容的包)
  • socket.io:^2.2.0
  • d3:3.5.17(?)
    • 我与d3的联系是,我知道它很旧,但我记得曾经尝试过升级,这严重破坏了一切,所以我害怕改变,因为这意味着在我的整个应用程序中更新数千行代码
  • JQuery:1.12.1(我知道它也很旧)
  • Chrome:78.0.3904.70(官方版本)(64位)
我试过的东西:

  • 将使用for循环的形式转换为使用forEach函数对我正在解析的数据进行迭代以创建表(因为我的一个朋友建议这可能会更宽容我的心跳,但我没有注意到区别)
  • 使用setTimeout尝试允许客户端有足够的时间发送/接收心跳消息(我测试了最多1s的超时,我认为这应该足够慷慨以保持心跳)
  • 使用异步函数尝试有效地让并行线程运行(我希望其中一个能够处理心跳)
  • 自己发出心跳信号,可以使用
    socket.emit(“ping”)
    socket.emit(“pong”)
    ,也可以使用自己的
    socket.emit(“心跳”)
  • 试图操纵服务器io对象的属性,以强制在触发超时之前允许更长的时间(如果有方法,我找不到正确的方法)
  • 尝试为客户端和服务器动态禁用断开连接功能(这似乎没有任何效果;请参阅下面的代码)
以下是导致问题的客户端代码(我最近尝试禁用“断开连接”消息的效果):

var shouldDisconnect=true;
socket.on('disconnect',disconnectFunc(shouldDisconnect));
功能断开功能(应断开){
返回函数(){
如果(应断开连接){
d3.选择All(“div”).remove();
d3.选择(“正文”).附加(“h3”).文本(“您与服务器的通信”+
“已被中断。请刷新此页面以重新连接。”);
}
}
}
//操作shouldDisconnect变量和
//socket.on(“断开”)回调在服务器端重复。这
//当我看到超时时,方法似乎没有任何影响。
//防止服务器断开连接
shouldDisconnect=false;
socket.removeListener(“断开”,disconnectFunc(shouldDisconnect));
socket.on(“断开”,disconnectFunc(shouldldisconnect));
socket.emit(“setDiconnect”,false);
//创建一个原始CSV数据表,我们已经提供
var rawDataDiv=rawTableContainer.append(“div”)
.attr(“id”,“rawDataDiv”)
.attr(“类别”、“col-md-12”)
.样式(“宽度”,函数(){
返回(this.parentNode.clientWidth-60)+“px”;
})
.样式(“高度”,“500px”)
.style(“边框”,“纯黑1px”)
.样式(“边距”,“15px 20px 15px”)
.样式(“溢出”、“滚动”);
var rawDataTable=rawDataDiv.append(“表”)
.attr(“id”,“rawDataTable”)
.attr(“类别”、“表格”);
//对键进行排序,将指定的键保留为第一个键
var dataKeys=Object.keys(csvContents[0]);
数据键拼接(dataKeys.indexOf(firstKey),1);
dataKeys=[firstKey].concat(dataKeys.sort());
//对对象进行排序
排序((a,b)=>(a[dataKeys[0]]>b[dataKeys[0]])?1:-1);
//创建表的第一行
var firstRow=rawDataTable.append(“thead”).append(“tr”);
var i;
对于(i=0;ivar shouldDisconnect = true;

socket.on('disconnect', disconnectFunc(shouldDisconnect));

function disconnectFunc(shouldDisconnect) {
    return function() {
        if (shouldDisconnect) {
            d3.selectAll("div").remove();
            d3.select("body").append("h3").text("Your communication with the server " +
                "has been interrupted. Please refresh this page to reconnect.");
        }
    }
}

// Similar logic in manipulating a shouldDisconnect variable and the
// socket.on("disconnect") callbacks is repeated server-side. This
// approach doesn't seem to have any effect on when I see timeouts.



// Prevent the server from disconnecting
shouldDisconnect = false;
socket.removeListener("disconnect", disconnectFunc(shouldDisconnect));
socket.on("disconnect", disconnectFunc(shouldDisconnect));
socket.emit("setDiconnect", false);

// Create a table of the raw CSV data that we have been provided
var rawDataDiv = rawTableContainer.append("div")
    .attr("id", "rawDataDiv")
    .attr("class", "col-md-12")
    .style("width", function () {
        return (this.parentNode.clientWidth - 60) + "px";
    })
    .style("height", "500px")
    .style("border", "solid black 1px")
    .style("margin", "15px 20px 15px")
    .style("overflow", "scroll");

var rawDataTable = rawDataDiv.append("table")
    .attr("id", "rawDataTable")
    .attr("class", "table");

// Sort the keys, leaving the specified key as the first key
var dataKeys = Object.keys(csvContents[0]);
dataKeys.splice(dataKeys.indexOf(firstKey), 1);
dataKeys = [firstKey].concat(dataKeys.sort());

// Sort the objects
csvContents.sort((a, b)=> (a[dataKeys[0]] > b[dataKeys[0]]) ? 1 : -1 );

// Create the first row of the table
var firstRow = rawDataTable.append("thead").append("tr");
var i;
for (i = 0; i < dataKeys.length; i++) {
    firstRow.append('th').attr("scope", "col").append("p").text(dataKeys[i]);
}

// Create each individual row of the table
rawDataTable = rawDataTable.append("tbody");
csvContents.forEach(async function(csvRow) {
    var nextRow = rawDataTable.append("tr")

        // Highlight row when mousing over
        .on("mouseover", function() {
            d3.select(this).classed("selected-row", true)
                .selectAll("td").style("background-color", "yellow");
        })
        .on("mouseout", function() {
            d3.select(this).classed("selected-row", false)
                .selectAll("td").style("background-color", "white");
        });

        // Create each entry for the current row
        dataKeys.forEach(async function(dataKey, i) { setTimeout( function() {
            var td;
            if (dataKey === dataKeys[0]) {
                td = nextRow.append("th").attr("scope", "row");
            }
            else {
                td = nextRow.append('td')

                    // Highlight column when mousing over
                    // Code adapted from https://stackoverflow.com/questions/38131000/how-to-highlight-a-column-in-html-table-on-click-using-js-or-jquery
                    .on("mouseover", function() {
                        var index = $(this).index();
                        $("#rawDataTable tr").each(function(i, tr) {
                            $(tr).find('td').eq(index-1).css("background-color", "yellow");
                        });
                    })
                    .on ("mouseout", function() {
                        var index = $(this).index();
                        $("#rawDataTable tr").each(function(j, tr) {
                            $(tr).find('td').eq(index-1).each(function(k, td) {
                                if (!$(tr).hasClass("selected-row")) {
                                    $(td).css("background-color", "white");
                                }
                            });
                        });
                    });

                // Add an ID and tooltip for each td
                var observationName = csvRow[firstKey];
                td.attr("id", "o-" + observationName.replace(/\/|<|>|\.| |'/g, "-") + "--a-" +  dataKey.replace(/\/|<|>|\.| |'/g, "-")).attr("title", observationName + ", " +  dataKey);
            }

            td.append("p").text(csvRow[dataKey]);

    }, 200) });
});

socket.removeListener("disconnect", disconnectFunc(shouldDisconnect));
shouldDisconnect = true;
socket.on("disconnect", disconnectFunc(shouldDisconnect));
socket.emit("setDiconnect", true);