我在我的项目服务器发送的事件中使用,其中JS正在调用PHP页面,比如说 eventserver.php ,它基本上包含一个无限循环,它检查一个事件的存在。 $ _SESSION变量。 在我的第一次实现时,这导致我的网站挂起,因为事件服务器在会话上锁定并且在超时到期之前没有释放它;但是,我设法通过在循环中连续使用session_write_lock()和session_start()锁定/解锁会话来解决此问题。
这实际上导致了很多php警告(在apache error.log上)说“无法发送会话缓存限制器 - 已经发送的标头”,“无法发送会话cookie”等等。
在这里发布一些代码
session_start();
header('Cache-Control: no-cache');
header('Content-Type: text/event-stream');
class EventServer
{
public function WaitForEvents( $eventType )
{
// ... do stuff
while( true )
{
// lock the session to this instance
session_start();
// ...check/output the event
ob_flush();
flush();
// unlock the session
session_write_close();
sleep( 1 );
}
}
}
由于
答案 0 :(得分:0)
这不是一个好主意。 HTTP是一种请求 - 响应协议,因此如果您希望服务器 - 客户端通信是双向的,则需要查看websockets或类似内容。还有类似"长轮询"和#34;心脏跳动"
如果你想要一个事件循环,可以尝试使用apache tomcat中的servlet。
由于您的设计,您将因问题而陷入困境。
如果您只是想从javascript到PHP发送消息,请查看ajax。
确保您了解正在使用的技术堆栈的概述:)
答案 1 :(得分:0)
您不需要SSE的无限循环。 EventSource保持与服务器的开放连接,客户端将读取服务器端数据的任何更新。
答案 2 :(得分:0)
我正在做与OP相同的事情并遇到同样的问题。其中一些答案并不了解eventSource应该如何工作。我的代码与您的代码相同,并使用会话变量来了解用户在哪个视图上驱动哪些数据在服务器触发时返回。它是实时协作应用程序的一部分。
我只是在@
前加session_start()
来抑制日志中的警告。不是一个真正的解决方案,但它可以防止日志填满。
或者,不确定它对您的应用程序的效果如何,但您可以使用ajax将正在监视的会话变量写入数据库,然后您的eventSource脚本可以监视DB中的更改而不必启动会话。
答案 3 :(得分:0)
可能是因为您在代码中两次启动了会话。不要在循环开始时而是在sleep()
之后重新启动会话。