我有一个几乎没有问题的服务器发送事件 (SSE)实现。我遇到的唯一问题是“一个用户可以与服务器建立许多连接”。基本上,如果用户打开多个 Web 浏览器的选项卡,每个选项卡都会向服务器创建一个全新的服务器发送事件请求,这会导致来自单个用户的许多请求运行。
为了解决这个问题,我想在 Javascript 的SharedWorker中运行 SSE 。
这意味着我只有一个 SSE 与 SharedWorker 进行通信。然后,每个页面/Web 浏览器都将与 SharedWorker 进行通信。这给了我每个用户只允许一个 SSE 的优势。
这就是我的 SSE 目前在没有任何类型工人的情况下工作的方式。
$(function(){
//connect to the server to read messages
$(window).load(function(){
startPolling( new EventSource("poll.php") );
});
//function to listen for new messages from the server
function startPolling(evtSource){
evtSource.addEventListener("getMessagingQueue", function(e) {
var data = JSON.parse(e.data);
//handle recieved messages
processServerData(data);
}, false);
evtSource.onerror = function(e) {
evtSource.close();
};
}
});
我想运行相同的设置。但是,我想在 javascript 的 SharedWorker 中运行它,以消除每个用户拥有多个 SSE。
我正在努力实施 SharedWorker。这是我到目前为止尝试过的
我创建了一个名为worker.js
并将此代码添加到其中的文件
var ports = [] ;
onconnect = function(event) {
var port = event.ports[0];
ports.push(port);
port.start();
var serv = new EventSource(icwsPollingUrl)
serv.addEventListener("getMessagingQueue", function(e) {
var data = JSON.parse(e.data);
processServerData(data);
}, false);
}
然后在我想列出消息的页面上,我有这个代码
$(function(){
$(window).load(function(){
var worker = new SharedWorker("worker.js");
worker.port.start();
worker.port.onmessage = function(e) {
console.log(e.data);
console.log('Message received from worker');
}
});
});
我在这里想念什么?
我究竟做错了什么?
如何更正实施?
已编辑
根据@Bergi 下面的评论,这是我的实现的更新版本,它仍然没有向连接器发布消息。我在代码中添加了注释,解释了对代码发生了什么的理解。
在登陆页面上,即index.php
我像这样连接到我的 SharedWorker
$(function($){
//establish connection to the shared worker
var worker = new SharedWorker("/add-ons/icws/js/worker1.js");
//listen for a message send from the worker
worker.port.addEventListener("message",
function(event) {
console.log(event.data);
}
, false
);
//start the connection to the shared worker
worker.port.start();
});
这是我的worker1.js
文件包含的代码
var ports = [] ;
//runs only when a new connection starts
onconnect = function(event) {
var port = event.ports[0];
ports.push(port);
port.start();
//implement a channel for a communication between the connecter and the SharedWorker
port.addEventListener("message",
function(event) {
listenForMessage(event, port);
}
);
}
//reply to any message sent to the SharedWorker with the same message but add the phrase "SharedWorker Said: " to it
listenForMessage = function (event, port) {
port.postMessage("SharedWorker Said: " + event.data);
}
//runs every time and post the message to all the connected ports
function readNewMessages(){
var serv = new EventSource(icwsPollingUrl)
serv.addEventListener("getMessagingQueue", function(e) {
var queue = JSON.parse(e.data);
notifyAllPorts(queue);
}, false);
}
//check all open ports and post a message to each
function notifyAllPorts(msg){
for(i = 0; i < ports.length; i++) {
ports[i].postMessage(msg);
}
}
这是我的另一个版本worker1.js
var ports = [] ;
//runs only when a new connection starts
onconnect = function(event) {
var port = event.ports[0];
ports.push(port);
port.start();
//implement a channel for a communication between the connecter and the SharedWorker
port.addEventListener("message",
function(event) {
listenForMessage(event, port);
}
);
}
//reply to any message sent to the SharedWorker with the same message but add the phrase "SharedWorker Said: " to it
listenForMessage = function (event, port) {
port.postMessage("SharedWorker Said: " + event.data);
}
readNewMessages();
//runs every time and post the message to all the connected ports
function readNewMessages(){
console.log('Start Reading...');
var serv = new EventSource(icwsPollingUrl);
serv.addEventListener("getMessagingQueue", function(e) {
var queue = JSON.parse(e.data);
console.log('Message Received');
console.log(queue);
notifyAllPorts(queue);
}, false);
}
//check all open ports and post a message to each
function notifyAllPorts(msg){
for(i = 0; i < ports.length; i++) {
ports[i].postMessage(msg);
}
}