单击按钮后为所有连接的用户重新加载页面
Reload page for all connected user after one's clicking a button
@LSerni 我也使用数据库编辑了代码,但我仍然被阻止:(
它执行 clicked.php 但检查状态似乎不起作用。
我在 table 中有 2 个字段,如果第二个字段高于第一个,则页面必须重新加载,但目前情况并非如此,clicked.php 文件有效美好的。检查-status.php:
<?php
$reply = [ 'status' => 'success', 'pressed' => false ];
for ($sec = 0; $sec < 60; $sec++) {
// ... check whether anyone pressed the button ...
$mysqli = new mysqli("localhost", "risicov19", "Edukapol19", "my_risicov19");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
$sql = "SELECT pre FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val1 = $row['pre'];
}
$sql = "SELECT data FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val2 = $row['data'];
}
if($val2 > $val1){
$sql = "UPDATE data SET pre = '" .$val2. "'";
if ($mysqli->query($sql) === TRUE) {
}
$reply['pressed'] = true;
break;
}
sleep(1);
}
die(json_encode($reply);
和clicked.php:
<?php
$mysqli = new mysqli("localhost", "risicov19", "Edukapol19", "my_risicov19");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
$sql = "SELECT data FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val = $row['data'];
}
$agg = $val + 1;
$sql = "UPDATE data SET data = '" .$agg. "'";
if ($mysqli->query($sql) === TRUE) {
}
die(json_encode([ 'status' => 'success' ]));
您需要让 其他 用户知道其中一个用户何时单击了按钮。
正如@balzacLeGeek 观察到的,这是 Web 套接字的工作。但是您也可以在 AJAX 中执行此操作,使用暂停的 AJAX 调用或多或少像这样:
var refresher = function() {
// CLIENT timestamp - beware of server time zones!
const since = Date.now() / 1000;
$.post('check-status.php', { since: since }).then(reply => {
if (reply.pressed) {
// do_reload();
} else {
// display some small animation to let user know we checked
}
// Schedule another round.
window.setTimeout(refresher, 10);
});
};
在页面中,当它加载时,只需调用 refresher() 它就会开始检查刷新。
检查状态函数被连续调用,这将导致系统负载不可接受。但是由于它 等待 服务器到 return,我们可以这样实现它:
<?php
$reply = [ 'status' => 'success', 'pressed' => false ];
for ($sec = 0; $sec < 60; $sec++) {
// ... check whether anyone pressed the button ...
if (file_exists('pressed.json')) {
if (filemtime('pressed.json') > $_POST['since']) {
// return immediately.
$reply['data'] = json_decode(file_get_contents('pressed.json'), true);
$reply['pressed'] = true;
break;
}
}
sleep(1);
}
header("Content-Type: application/json;charset=UTF-8");
die(json_encode($reply);
通话 暂停 长达 60 秒或直到有人按下按钮;在这种情况下,一秒钟内,所有挂起的电话return,以及所有用户的屏幕重新加载;他们会立即发出另一个呼叫,等待下一次按下,依此类推。
您可能想玩一下暂停时间,或者实施一个 setInterval 看门狗,以确保正确发出刷新调用(如果一个调用失败,则该客户端的整个周期停止;客户端“死了”。所以在刷新时你设置一个全局时间戳变量,setInterval 看门狗函数验证时间戳永远不会早于暂停时间加上合理的余量,比如 2 秒。如果是,看门狗只是调用 refresher() 来重新启动循环,并且可能会显示一个简短的动画“您的 Internet 连接有问题”)。
按下函数只是创建一个文本文件以响应按钮按下。或者你可以使用数据库,或共享内存区域,或 Redis 或其他任何东西:
$('#button').on('click', ()=> {
$.post('/clicked.php',
{
user: 'lserni', // or read from a global application object
message: $('#message').val()
}
});
脚本被调用,对于文件情况,你有一个竞争条件(如果两个人同时按下按钮怎么办?):
<?php
$written = file_put_contents(
'pressed.json',
json_encode([
'message' => $_POST['message'],
'user' => $_POST['user'],
'date' => date('d/m/Y H:i:s'),
]),
LOCK_EX
);
header('Content-Type: application/json; charset=UTF-8');
if (!$written) {
die(json_encode([ 'status' => 'failure' ]));
}
die(json_encode([ 'status' => 'success' ]));
在文件的情况下,检查文件是否存在是不够的,因为在第一次点击后文件总是存在的,如果十个客户端检查,第一个不能简单地删除文件(其他九个什么也找不到,并假设没有人按下按钮)。
所以,每个客户端记录它最后一次运行按钮检查的时间,并且服务器回复创建新闻文件是否晚于请求的时间。这也不理想(上次时间没有保存,而是读取时钟,所以有一小段时间 window 不会检测到按下;并且客户端时间可能与服务器时间不同),但应该足够开始了。
简化版(刚刚测试)
这使用三个文件 poll.php、poll.html 和 click.php。每个客户端记录分配给最后一个答题器的随机标识符,并指示轮询器忽略该标识符。这样,轮询器将等待直到出现不同的标识符,这意味着有人点击了。
所有客户端都在同一页面上(如果同一页面打开超过 X 个连接,浏览器可能会报错,脚本将无法运行。我在这里使用了 3 个)。
poll.html:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<style>
div {
display: inline-block;
width: 150px;
height: 3em;
border: 1px solid red;
padding: 2px;
}
</style>
</head>
<body>
<div><button></button><br /><input type="text" size="12" /></div>
</body>
<script>
function freshener(clientName, x) {
$.post('poll.php',
{
client: clientName,
ignore: x || 0
}
)
.then(reply => {
// Identify our client
let client = $('#'+clientName).closest('div');
client.find('input').val(reply.text);
window.setTimeout(function() { freshener(clientName, reply.ignore); }, 1);
});
}
$(_=>{
let btn = $('div').clone();
$('div').remove();
for (var i = 1; i < 4; i++) {
$('body').append(btn.clone().find('button').attr({ id: "x"+i }).text("X"+i).end());
// Create a poller for object x(i)
freshener("x"+i);
}
$('body').on('click', 'div', function(event) {
let clientName = $(this).find('button').attr('id');
$.post('click.php', { client: clientName });
});
});
</script>
</html>
poll.php:
<?php
$reply = [ 'status' => 'success', 'pressed' => false, 'ignore' => $_POST['ignore'], 'text' => 'WAIT ' . date('H:i:s') ];
$wait = rand(2, 5);
for ($sec = 0; $sec < $wait; $sec++) {
if (file_exists('pressed.json')) {
$data = json_decode(file_get_contents('pressed.json'), true);
if ($data['ignore'] != $_POST['ignore']) {
// return immediately.
$reply['text'] = $data['text'];
$reply['pressed'] = true;
$reply['ignore'] = $data['ignore'];
break;
}
}
sleep(1);
}
header("Content-Type: application/json;charset=UTF-8");
die(json_encode($reply));
最后是一个非常简单的 click.php:
error_reporting(E_ALL);
ini_set("display_errors", true);
// Someone clicked!
$time = date("H:i:s");
file_put_contents(
'pressed.json',
json_encode([
'text' => "client {$_POST['client']}",
'ignore' => floor(rand())
]),
LOCK_EX
);
您可以手动调用 click.php 脚本来查看文件创建是否有错误。
当用户单击按钮时,您可以使用名为 redirect() 的 JavaScript 方法,此方法将重定向到您在重定向方法中提到的特定路径
@LSerni 我也使用数据库编辑了代码,但我仍然被阻止:(
它执行 clicked.php 但检查状态似乎不起作用。
我在 table 中有 2 个字段,如果第二个字段高于第一个,则页面必须重新加载,但目前情况并非如此,clicked.php 文件有效美好的。检查-status.php:
<?php
$reply = [ 'status' => 'success', 'pressed' => false ];
for ($sec = 0; $sec < 60; $sec++) {
// ... check whether anyone pressed the button ...
$mysqli = new mysqli("localhost", "risicov19", "Edukapol19", "my_risicov19");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
$sql = "SELECT pre FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val1 = $row['pre'];
}
$sql = "SELECT data FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val2 = $row['data'];
}
if($val2 > $val1){
$sql = "UPDATE data SET pre = '" .$val2. "'";
if ($mysqli->query($sql) === TRUE) {
}
$reply['pressed'] = true;
break;
}
sleep(1);
}
die(json_encode($reply);
和clicked.php:
<?php
$mysqli = new mysqli("localhost", "risicov19", "Edukapol19", "my_risicov19");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
$sql = "SELECT data FROM data";
$rs = mysqli_query($mysqli, $sql);
while($row = mysqli_fetch_assoc($rs)) {
$val = $row['data'];
}
$agg = $val + 1;
$sql = "UPDATE data SET data = '" .$agg. "'";
if ($mysqli->query($sql) === TRUE) {
}
die(json_encode([ 'status' => 'success' ]));
您需要让 其他 用户知道其中一个用户何时单击了按钮。
正如@balzacLeGeek 观察到的,这是 Web 套接字的工作。但是您也可以在 AJAX 中执行此操作,使用暂停的 AJAX 调用或多或少像这样:
var refresher = function() {
// CLIENT timestamp - beware of server time zones!
const since = Date.now() / 1000;
$.post('check-status.php', { since: since }).then(reply => {
if (reply.pressed) {
// do_reload();
} else {
// display some small animation to let user know we checked
}
// Schedule another round.
window.setTimeout(refresher, 10);
});
};
在页面中,当它加载时,只需调用 refresher() 它就会开始检查刷新。
检查状态函数被连续调用,这将导致系统负载不可接受。但是由于它 等待 服务器到 return,我们可以这样实现它:
<?php
$reply = [ 'status' => 'success', 'pressed' => false ];
for ($sec = 0; $sec < 60; $sec++) {
// ... check whether anyone pressed the button ...
if (file_exists('pressed.json')) {
if (filemtime('pressed.json') > $_POST['since']) {
// return immediately.
$reply['data'] = json_decode(file_get_contents('pressed.json'), true);
$reply['pressed'] = true;
break;
}
}
sleep(1);
}
header("Content-Type: application/json;charset=UTF-8");
die(json_encode($reply);
通话 暂停 长达 60 秒或直到有人按下按钮;在这种情况下,一秒钟内,所有挂起的电话return,以及所有用户的屏幕重新加载;他们会立即发出另一个呼叫,等待下一次按下,依此类推。
您可能想玩一下暂停时间,或者实施一个 setInterval 看门狗,以确保正确发出刷新调用(如果一个调用失败,则该客户端的整个周期停止;客户端“死了”。所以在刷新时你设置一个全局时间戳变量,setInterval 看门狗函数验证时间戳永远不会早于暂停时间加上合理的余量,比如 2 秒。如果是,看门狗只是调用 refresher() 来重新启动循环,并且可能会显示一个简短的动画“您的 Internet 连接有问题”)。
按下函数只是创建一个文本文件以响应按钮按下。或者你可以使用数据库,或共享内存区域,或 Redis 或其他任何东西:
$('#button').on('click', ()=> {
$.post('/clicked.php',
{
user: 'lserni', // or read from a global application object
message: $('#message').val()
}
});
脚本被调用,对于文件情况,你有一个竞争条件(如果两个人同时按下按钮怎么办?):
<?php
$written = file_put_contents(
'pressed.json',
json_encode([
'message' => $_POST['message'],
'user' => $_POST['user'],
'date' => date('d/m/Y H:i:s'),
]),
LOCK_EX
);
header('Content-Type: application/json; charset=UTF-8');
if (!$written) {
die(json_encode([ 'status' => 'failure' ]));
}
die(json_encode([ 'status' => 'success' ]));
在文件的情况下,检查文件是否存在是不够的,因为在第一次点击后文件总是存在的,如果十个客户端检查,第一个不能简单地删除文件(其他九个什么也找不到,并假设没有人按下按钮)。
所以,每个客户端记录它最后一次运行按钮检查的时间,并且服务器回复创建新闻文件是否晚于请求的时间。这也不理想(上次时间没有保存,而是读取时钟,所以有一小段时间 window 不会检测到按下;并且客户端时间可能与服务器时间不同),但应该足够开始了。
简化版(刚刚测试)
这使用三个文件 poll.php、poll.html 和 click.php。每个客户端记录分配给最后一个答题器的随机标识符,并指示轮询器忽略该标识符。这样,轮询器将等待直到出现不同的标识符,这意味着有人点击了。
所有客户端都在同一页面上(如果同一页面打开超过 X 个连接,浏览器可能会报错,脚本将无法运行。我在这里使用了 3 个)。
poll.html:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<style>
div {
display: inline-block;
width: 150px;
height: 3em;
border: 1px solid red;
padding: 2px;
}
</style>
</head>
<body>
<div><button></button><br /><input type="text" size="12" /></div>
</body>
<script>
function freshener(clientName, x) {
$.post('poll.php',
{
client: clientName,
ignore: x || 0
}
)
.then(reply => {
// Identify our client
let client = $('#'+clientName).closest('div');
client.find('input').val(reply.text);
window.setTimeout(function() { freshener(clientName, reply.ignore); }, 1);
});
}
$(_=>{
let btn = $('div').clone();
$('div').remove();
for (var i = 1; i < 4; i++) {
$('body').append(btn.clone().find('button').attr({ id: "x"+i }).text("X"+i).end());
// Create a poller for object x(i)
freshener("x"+i);
}
$('body').on('click', 'div', function(event) {
let clientName = $(this).find('button').attr('id');
$.post('click.php', { client: clientName });
});
});
</script>
</html>
poll.php:
<?php
$reply = [ 'status' => 'success', 'pressed' => false, 'ignore' => $_POST['ignore'], 'text' => 'WAIT ' . date('H:i:s') ];
$wait = rand(2, 5);
for ($sec = 0; $sec < $wait; $sec++) {
if (file_exists('pressed.json')) {
$data = json_decode(file_get_contents('pressed.json'), true);
if ($data['ignore'] != $_POST['ignore']) {
// return immediately.
$reply['text'] = $data['text'];
$reply['pressed'] = true;
$reply['ignore'] = $data['ignore'];
break;
}
}
sleep(1);
}
header("Content-Type: application/json;charset=UTF-8");
die(json_encode($reply));
最后是一个非常简单的 click.php:
error_reporting(E_ALL);
ini_set("display_errors", true);
// Someone clicked!
$time = date("H:i:s");
file_put_contents(
'pressed.json',
json_encode([
'text' => "client {$_POST['client']}",
'ignore' => floor(rand())
]),
LOCK_EX
);
您可以手动调用 click.php 脚本来查看文件创建是否有错误。
当用户单击按钮时,您可以使用名为 redirect() 的 JavaScript 方法,此方法将重定向到您在重定向方法中提到的特定路径