我在具有LAMP配置的共享托管空间(Aruba)上运行服务器,具有两组独立的PHP页面,一组用于管理员,一组用于多个客户端(想象一下管理员提交问题的问答游戏) .
我想实现这种行为:
-
管理员按下按钮并释放问题
-
在十秒内(甚至是立即,但并非严格要求)的任何时间,所有客户必须在同一时间显示带有问题文本的页面 .
为实现这一目标,我想到了不同的解决方案:
-
Web sockets (不可行,因为我无法在我的网页上安装服务器组件)
-
Trigger file 由管理员生成;客户端将定期(~10秒)轮询(
setInterval()
)以查看是否存在此文件,并且根据文件的创建时间(或从文件名或文件内容中读取的等效时间戳),客户端将开始倒计时(setTimeout()
)为必须触发新页面的剩余时间,以确保所有客户端最终同时触发(十分之一秒) -
Trigger via database (与触发文件基本相同,但可能更慢) .
我在PHP和Javascript中尝试了第二个解决方案(在客户端管理触发器文件的读取),但是当连接的客户端不止时它们都会失败:
-
PHP 显然失败了,因为Apache不支持许多同步线程并且以某种方式卡住了
-
Javascript 偶尔会错过识别本地目录中存在的文件(连接多个客户端
XMLHttpRequest.status
错误地返回404
,即使触发器文件存在) - 我甚至为不同的客户端创建了单独的触发器文件,以确保没有并发冲突 .
有关为什么_416044偶尔会失败的任何提示,或有关更好地实现此行为的建议?
先感谢您 .
2 回答
编辑:我原来的答案中没有完全理解这个问题 . 这是我精确的答案:
根据您目前的限制,我只看到了实现同步服务器响应的一种方法 . 首先,您需要实现HTML5 SSE(服务器端事件) . 当您的服务器准备好向客户端发送消息时,触发SSE发送到每个客户端 . 此事件不需要发送任何数据,因此不需要同时联系客户端 . 该事件告诉客户端对php ajaxHandler执行ajax调用 .
在来自客户端的每次ajax调用期间,服务器将在您创建的某个表中检查数据库中“waitingClients”的值 . 如果值为0,则将值设置为1.如果该值大于0,则将waitingClients值增加1.在每次ajax调用增加数据库值之后,将在while循环中暂停各个ajax调用,直到'waitingClients '等于'totalClients'的值 . 我建议您在数据库中创建一些记录活动客户端数量的条目 . 这使您的'totalClients'值更具动态性 .
你可能会遇到问题,ajax调用会在30秒后超时 . 由于您只返回数据库值,我怀疑您是否会遇到此问题,除非客户端的连接挂起 .
这是一些示例代码(未经测试):
HTML
阿贾克斯:
PHP Ajax处理程序
你考虑过长时间的民意调查吗?有关如何使用PHP执行此操作的示例,请参阅https://github.com/panique/php-long-polling . 由于必须保持活动的apache和php进程的数量,这将无法很好地扩展,但对于少数客户端来说会很好 . 如果你需要它可以扩展,那么我会考虑将服务器技术转换为像hack(如PHP;参见http://hacklang.org/)或节点这样的东西 .