本人PHP水平不高,算是新手。
因为要制作一个设备参数监控的功能,所以我用到了HTML5新的技术标准,SSE(server send event)服务器发送事件。
后台框架基于ThinkPHP,代码大致如下。class DataAction extends Action { // 将通过前台传递的当前选择节点信息写入SESSION
public function selectNode()
{
$_SESSION['nodeAttr'] = $_GET['attr'];
$_SESSION['selectNode'] = $_GET['node'];
} // 数据输出函数,基于SSE
public function stream()
{
header("Content-Type: text/event-stream\n");
header('Cache-Control: no-cache');
while (1)
{
$key = $_SESSION['selectNode'];
$attr = $_SESSION['nodeAttr'];
$value = D('Value');
$paramList = $value->join("sys_deviceparam ON cfg_deviceparamvalue.DeviceParamInfoID = sys_deviceparam.DeviceParamInfoID")->where("DeviceID = '$key'")->select();
$Paramstr = json_encode($paramList);
echo "event:newdata\n";
echo "data:{\042Rows\042:$Paramstr}"."\n\n";
ob_flush();
flush();
sleep(1);
}
}
}
前台代码如下//建立SSE对象
source = new EventSource("__APP__/Data/stream");
source.addEventListener("newdata",function(event)
{
gdata = event.data;
gdata = JSON.parse(gdata); // gridManager是我的前端控件,这里可以不关注
gridManager.set({data : gdata});
gridManager.loadData();
})现在已经能达到我想要的结果,后台会实时推送新鲜的数据到前台。
不过还有一个新的问题,就是用户会切换显示的设备。
我之前的思路是,用户在切换设备时,通过一个GET向后台发送设备的ID信息,再有后台的selectNode方法写入SESSION。
而结果并不尽如人意。当前台触发改写SESSION的GET时,因为EventListener一直在抓去数据,所以会造成HTTP的阻塞,也就是说GET一直发不出去(或者是发出去但是没响应吧。。)。
当时想,会不会是因为SESSION被锁死,便用了session_write_close(),结果HTTP不阻塞了,但是SESSION中相关的字段还是没有被改写。。所以请教各位有没有相关的经验,或者有更好的解决思路?不胜感激
因为要制作一个设备参数监控的功能,所以我用到了HTML5新的技术标准,SSE(server send event)服务器发送事件。
后台框架基于ThinkPHP,代码大致如下。class DataAction extends Action { // 将通过前台传递的当前选择节点信息写入SESSION
public function selectNode()
{
$_SESSION['nodeAttr'] = $_GET['attr'];
$_SESSION['selectNode'] = $_GET['node'];
} // 数据输出函数,基于SSE
public function stream()
{
header("Content-Type: text/event-stream\n");
header('Cache-Control: no-cache');
while (1)
{
$key = $_SESSION['selectNode'];
$attr = $_SESSION['nodeAttr'];
$value = D('Value');
$paramList = $value->join("sys_deviceparam ON cfg_deviceparamvalue.DeviceParamInfoID = sys_deviceparam.DeviceParamInfoID")->where("DeviceID = '$key'")->select();
$Paramstr = json_encode($paramList);
echo "event:newdata\n";
echo "data:{\042Rows\042:$Paramstr}"."\n\n";
ob_flush();
flush();
sleep(1);
}
}
}
前台代码如下//建立SSE对象
source = new EventSource("__APP__/Data/stream");
source.addEventListener("newdata",function(event)
{
gdata = event.data;
gdata = JSON.parse(gdata); // gridManager是我的前端控件,这里可以不关注
gridManager.set({data : gdata});
gridManager.loadData();
})现在已经能达到我想要的结果,后台会实时推送新鲜的数据到前台。
不过还有一个新的问题,就是用户会切换显示的设备。
我之前的思路是,用户在切换设备时,通过一个GET向后台发送设备的ID信息,再有后台的selectNode方法写入SESSION。
而结果并不尽如人意。当前台触发改写SESSION的GET时,因为EventListener一直在抓去数据,所以会造成HTTP的阻塞,也就是说GET一直发不出去(或者是发出去但是没响应吧。。)。
当时想,会不会是因为SESSION被锁死,便用了session_write_close(),结果HTTP不阻塞了,但是SESSION中相关的字段还是没有被改写。。所以请教各位有没有相关的经验,或者有更好的解决思路?不胜感激
感谢版主的回复。
我现在想的思路是,在每次用户切换设备的事件发生时,先关闭EventListener,然后在回调函数里重新执行EventListener。
不知道版主有没有什么更好的解决思路呢?
你可以通过文件、数据库、共享内存等手段保存来自客户端的信息。
在 stream() 的“死循环”中检查是否有新的客户端指令(就像你检查session那样)
另外还应加上退出循环的指令