2015-04-02 58 views
0

我正在使用SSE事件将用户的朋友请求数从服务器推送到客户端。但是当我这样做时,网站的其他页面卡住并继续加载(可能是由于用户会话锁定)。如何将SSE事件数据推送到客户端,并且在会话运行时不让其他页面等待?如何使服务器发送事件(SSE)与PHP会话一起工作?

我在客户端的事件监听器,如下所示:

var evtSource = new EventSource("friend-req.php"); 
 
var eventList = $('#list'); //this is div's ID on xhtml page 
 
$(document).ready(function(){ 
 
\t 
 
$(function(){ 
 
\t evtSource.addEventListener("requests", function(e) { 
 
\t \t var newElement = document.createElement("li"); 
 
\t \t \t 
 
\t \t var obj = JSON.parse(e.data); 
 
\t \t newElement.innerHTML = "friend request count: " + obj.count; 
 
\t \t eventList.append(newElement); 
 
\t }, false); 
 
}); 
 
});

在服务器端,我使用的是事件,而环(作为SO建议通过大量的文章)。首先,我从数据库中获取当前会话用户的好友请求计数,然后针对事件的“请求”(客户端正在侦听)推送它。

<?php 

//friend-req.php file 

session_start(); 
header('Content-Type: text/event-stream'); 
header('Cache-Control: no-cache'); 
include_once 'db.php'; 

$db = new db(); 

while (1) { 
    $user = $_SESSION['user']; 
    $q = "select count(*) num from requests where status = 1 and id = $user"; 

    $result = $db->select($q) or die("Query Failed:" . $db->last_error); 

    if($result) 
    { 
     $r = $db->get_row($result); 
     echo "event: requests\n"; 
     echo 'data: {"count": "' . $r['num'] . '"}'; 
     echo "\n\n"; 
    } 
    ob_flush(); 
    flush(); 
    sleep(5); 
} 

?> 

问题是,当我运行客户端脚本时,它运行良好,但没有其他页面加载。我已经搜索了解决方案,但在SO和其他网站上都没有找到满意的答案。告诉我怎样才能发送会话的服务器端事件,而不是让其他页面等待(或者如果在方法中有任何缺陷/更好的方式这样做)

+0

你克服了这个问题吗?你是否让其他页面加载? BOS我也面临着与上海证券交易所同样的问题。 – Ram 2015-10-20 06:12:37

回答

1

我认为问题出在“session_start()”:每个会话锁一个文件在服务器,所以没有其他脚本可以开始使用相同的会话(它们都挂在他们的“session_start()”调用),直到第一个脚本结束和/或释放锁。您的脚本应读取循环外部的$用户,然后调用session_commit(),以便其他脚本可以运行。请记住,会话锁定总是会阻止脚本的并行执行:如果您已完成读取或修改会话变量,则始终在脚本中调用session_commit(),以便其他脚本可以在第一次完成其详细说明时运行(有关其他更详细的解决方案的Google)。例如,如果您的浏览器使用会话对您的php代码执行了大量异步AJAX调用,则非常重要:如果没有“session_commit()”,您将看到您的服务器在某个时间没有任何并行性地响应请求

相关问题