我在Windows 7 Pro上运行Apache。我使用XAMPP软件包安装了Apache。
我需要每秒调用一次API。为此,我创建了一个使用XMLHttpRequest
但是,我遇到了Web服务器Apache遇到允许的最大TCP连接的问题。当然,我可以增加服务器上允许的TCP连接,但这并没有解决我的问题,它只会修补它,直到服务器忙碌和过载。
对TCP问题进行故障排除后,我很清楚XMLHttpRequest
没有重用现有的TCP连接。它为每个请求/每秒打开一个新的TCP连接。我希望有1个TCP连接用于处理我的XMLHttpRequest
连接。
虽然我是唯一一个与服务器上的网站连接的用户,但我在Web服务器上启动了TCPView
以观察tcp连接。我从30个TCP连接开始,状态为TIME_WAIT
。每隔一秒钟后,再创建一个连接,直到达到大约122-130,然后停止。现在,服务器似乎每60秒回收一次连接,但仍然每秒XMLHttpRequest
生成一个新的TCP连接。
我也明白,每次加载页面时,客户端/浏览器都会因各种原因创建多个TCP连接。但是,我希望有一个TCP连接来处理我的XMLHttpRequest
并一遍又一遍地重新使用该连接。
我知道有些人可能会建议使用WebSockets
或Server-Sent-Events
,但就我而言,我无法做到。我必须保持我的ShardWorker实现。
问题
如何使XMLHttpRequest
重用开放式TCP连接?
以下是我的ShardWorker实现,即worker.js
var clients = new Array();
var xhr = null;
//runs only when a new connection starts
onconnect = function(event) {
var port = event.ports[0];
clients.push(port);
port.start();
//implement a channel for a communication between the connecter and the SharedWorker
port.addEventListener("message",
function(event) {
replyToClientMessage(event, port);
} , false
);
}
//reply to any message sent to the SharedWorker with the same message but add the phrase "SharedWorker Said: " to it
replyToClientMessage = function (event, port) {
port.postMessage("Worker Replied With: " + event.data);
}
//check all open clients and post a message to each
function notifyAllPorts(msg){
var len = clients.length;
var port;
for(i = 0; i < len; i++) {
port = clients[i];
port.postMessage(msg);
}
}
function checkQueue(cb) {
//create a new XMLHttpRequest only once
if (xhr == null) {
xhr = new XMLHttpRequest();
xhr.addEventListener("loadend", cb);
xhr.addEventListener("load", handlerMessageReceived);
}
xhr.open('GET', '/add-ons/icws/push.php', true);
xhr.send();
}
//handler a sucessfull request
function handlerMessageReceived()
{
var queue = JSON.parse(this.responseText);
notifyAllPorts(queue);
}
var promise = Promise.resolve(true);
setInterval(function () {
promise = promise.then(function () {
return new Promise(function (resolve) {
checkQueue(resolve);
});
});
}, 1000);
以下是我将Sharedworker投入使用的方法
//establish connection to the shared worker
var worker = new SharedWorker("/add-ons/icws/js/worker.js" );
//listen for a message send from the worker
worker.port.addEventListener("message",
function(event) {
console.log(event.data);
processServerData(event.data);
}
, false
);
worker.onerror = function(event){
console.log(event);
};
//start the connection to the shared worker
worker.port.start();