javascript - Javascript 服务器端事件:多个客户端监听单个服务器实例
问题描述
我想用多个客户端监听一个服务器实例来实现服务器端事件。当我的客户连接时,他们会创建一个新的服务器实例。我希望他们都听同一个实例。
以下片段描述了服务器,Client1 侦听“Ping”,Client2 侦听“Pong”。运行时,每个客户端都会创建一个新实例,如在浏览器中生成并显示的随机密钥所示。我的目标是让它们 bot 监听到同一个实例。我已经看了好几个小时,找到了很多信息并使用了她的库,但我宁愿只使用本机。这是在包括 bootstrap、jquery、socket.io 和其他库的 FreePBX 环境中运行的。
sse-serv.php:
<?php
date_default_timezone_set("America/New_York");
header("Content-Type: text/event-stream");
$key = rand(1111, 9999); // a random counter
$counter=0;
while ($counter < 100) {
// 1 is always true, so repeat the while loop forever (aka event-loop)
$curDate = date("Y-m-d H:i:s");
$msg=array();
$msg['count']=$counter;
$msg['time']=$curDate;
$msg['key']=$key;
$json_msg=json_encode($msg);
if ($ping) {
echo "event: ping\ndata: $json_msg \n\n";
$ping=false;
} else {
echo "event: pong\ndata: $json_msg \n\n";
$ping=true;
}
$counter++;
ob_end_flush();
flush();
if ( connection_aborted() ) break;
sleep(1);
}
?>
服务器每秒交替发送一个“Ping”或“Pong”事件。客户端显示的正是我所期望的,除了 RND $Key 是不同的,所以它们显然是不同的实例。(由于某种原因,它们都没有出现在 ps aux | grep sse-serv 中)。
sse-client1.php:
<?php
session_start();
require_once('include.php');
require_once('/etc/freepbx.conf');
$dt=date("Y-m-d H:i:s");
?>
<html>
<head>
<meta charset="UTF-8">
<title>Server-sent events demo</title>
</head>
<body>
<button>Close the connection</button>
<script>
var button = document.querySelector('button');
var evtSource = new EventSource('sse-serv.php');
console.log(evtSource.withCredentials);
console.log(evtSource.readyState);
console.log(evtSource.url);
var eventList = document.querySelector('ul');
evtSource.onopen = function() {
console.log("Connection to server opened.");
};
evtSource.onmessage = function(e) {
var newElement = document.createElement("li");
newElement.textContent = "message: " + e.data;
eventList.appendChild(newElement);
};
evtSource.onerror = function() {
console.log("EventSource failed.");
};
button.onclick = function() {
console.log('Connection closed');
evtSource.close();
};
evtSource.addEventListener("ping", function(e) {
var newElement = document.createElement("li");
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var ntime= h + ":" + m + ":" + s;
var obj = JSON.parse(e.data);
newElement.innerHTML = "Key: " + obj.key + ping at " + obj.time + " Local time: " + ntime + " counter: " + obj.count;
eventList.appendChild(newElement);
}, false);
</script>
</body>
</html>
Client2 与 client1 完全相同,只是它侦听“Pong”而不是“Ping”。
当我同时运行它们两个客户端时,我得到了这个:
客户1:
Key: 2642 ping at 2018-11-18 06:27:19 Local time: 6:27:19 counter: 1
Key: 2642 ping at 2018-11-18 06:27:21 Local time: 6:27:21 counter: 3
Key: 2642 ping at 2018-11-18 06:27:23 Local time: 6:27:23 counter: 5
Key: 2642 ping at 2018-11-18 06:27:25 Local time: 6:27:25 counter: 7
Key: 2642 ping at 2018-11-18 06:27:27 Local time: 6:27:27 counter: 9
客户2
Key: 1818 pong at 2018-11-18 06:27:18 Local time: 6:27:18 counter: 0
Key: 1818 pong at 2018-11-18 06:27:20 Local time: 6:27:20 counter: 2
Key: 1818 pong at 2018-11-18 06:27:22 Local time: 6:27:22 counter: 4
Key: 1818 pong at 2018-11-18 06:27:24 Local time: 6:27:24 counter: 6
Key: 1818 pong at 2018-11-18 06:27:26 Local time: 6:27:26 counter: 8
这个输出正是我想要的,除了不同的键证明每个客户端都在运行一个单独的 sse-serv.php 实例。我需要他们同时收听 sse-serv.php 的现有实例,该实例将作为守护进程运行并向所有客户端广播。我怎样才能做到这一点?
解决方案
这正是我所需要的。所以现在我有我自己的用 PHP 和客户端库编写的服务器,可以通过 ws:// wss:// tcp:// ssl:// 处理连接
推荐阅读
- azure-devops - 如何在 Azure Devops 中显示显示构建指标的仪表板
- swift - UITableview 与单元格两个单元格
- javascript - 如何使用 autoColumns 添加标题过滤器?
- css - 如何使用 WordPress 子主题/css 定制器替换所有具有该值的 css 类/属性中的特定属性值
- python - 定义一个相对的首选函数 - python turtle
- apache-spark - 如何优化 Spark 结构化流应用程序中的执行程序实例数量?
- nlp - 有没有一种机制可以从一袋名词中过滤出普通名词?
- c# - C# 如何写入数组的每个部分?
- json - Microsoft Graph FindMeetingTimes API - 仅返回 5 个位置?
- javascript - 是什么导致 Uint8Array 中字符串的索引偏移?