我写的一个PHP即时聊室天方案

pgmsoul 2013-03-29 09:37:38
并没有写具体的数据交互, 只是实现了核心功能的原理, 即时的连续的传输数据给客户端.


ajax = function(method, url, data) {
var objxml = jsuse.createXMLHttpRequest(); //自己写这个函数, 我使用了一个库.
if (url.indexOf("http://") != 0) {
url = jsuse.BASE_URL + url;
}
objxml.open(method, url, true); //异步调用
//objxml.setRequestHeader("Content-type", "application/x-octet-stream");
var pos = 0;
objxml.onreadystatechange = function() {
if (objxml.readyState == 4) {
if (objxml.status == "200") {
document.write("200 OK");
} else {
//document.write(objxml.status);
}
} else if(objxml.readyState == 3) {
var str = objxml.responseText;
document.write(str.substr(pos));
pos = str.length;
} else {
document.write(objxml.readyState+"<br />");
}
}
try {
objxml.send(data);
} catch (e) {
return false;
}
return true;
}
jsuse(function(){
ajax("post","test.php",""); //这一句会在onLoad里加载, 可以写在body的onLoad里.
});


set_time_limit(0); //设置页面永不超时
for($i=0;$i<3000;$i++){ //先把浏览器缓存冲掉, 不同浏览器这个值不同.
echo " ";
}
ob_implicit_flush(true); //设置PHP实时输出
$n = 0;
while(true) {
echo "$n yeah :-))))<br />";
@ob_flush();//刷新缓冲.
sleep(1);
$n++;
}

测试客户端可以持续的接收到服务端的数据.

我想问的是这种方案在客户端较多的时候资源占用怎样? 实际上是一个持续连接, 资源占用比播放视频低得多. 另外, 聊天的时候, 用户提交的文本应该是用一个数据库存储和协调的, 这就意味这这个数据库是持续打开的, 用户多了以后会不会有问题?
...全文
271 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
StatusNet 开源微博系统,参照那个吧,现在已经比较成熟了。
stch12132324 2013-03-29
  • 打赏
  • 举报
回复
让客户端ajax定时去调接口就行了,没必要做死循环
改一下昵称 2013-03-29
  • 打赏
  • 举报
回复
引用 10 楼 pgmsoul 的回复:
引用 8 楼 dream1206 的回复:回应3: 对ajax来说,只有当服务器执行完毕,ajax的回调函数才会被调用。因此你所说的长连接实际上是起不作用的,也许你根本没有测试过你写的代码。 无语. 我没测试, 难道你测试了? 说句惹你们不高兴的话, 也是有勋章的人了, 技术上认真点.
抱歉是我的无知,之前一直以为只有当响应内容全部加载完毕,responseText才会被赋值。
pgmsoul 2013-03-29
  • 打赏
  • 举报
回复
引用 8 楼 dream1206 的回复:
回应3: 对ajax来说,只有当服务器执行完毕,ajax的回调函数才会被调用。因此你所说的长连接实际上是起不作用的,也许你根本没有测试过你写的代码。
无语. 我没测试, 难道你测试了? 说句惹你们不高兴的话, 也是有勋章的人了, 技术上认真点.
xuzuning 2013-03-29
  • 打赏
  • 举报
回复
先说一下代码问题: 1、你在函数中用了 document.write ,那么你的程序能正常运行吗? 2、把浏览器缓存冲掉,这一动作需在每次输出时做。你只在循环外做一次,能保证气候的数据能实时显示吗? 回到方案上: 每一次执行 ajax 都将产生一个新的 http 会话,也就是服务器每次都会执行一个php程序的副本。那么,你让被执行的php程序处于死循环中的意义何在?
pgmsoul 2013-03-29
  • 打赏
  • 举报
回复
另外还有2个问题: 1. 服务端是每隔一秒, 刷新一下数据库, 看有没有新数据. 有没有优化的方案? 2. 不同的聊天室, 数据是没有关联的, 但是如果把不同的聊天室数据保存在同一个表中(毕竟, 这些数据如果不需要保存的话, 实际上一个聊天室占用的存储空间是很小的, 格式又相同, 没有必要每个聊天室建一个表), 通过一个标识来区分, 那么不同的聊天室读写数据库会不会互相加锁, 降低效率.
改一下昵称 2013-03-29
  • 打赏
  • 举报
回复
回应3: 对ajax来说,只有当服务器执行完毕,ajax的回调函数才会被调用。因此你所说的长连接实际上是起不作用的,也许你根本没有测试过你写的代码。
danhuang 2013-03-29
  • 打赏
  • 举报
回复
像这种定时请求服务器资源的PHP应用对服务器的压力会很大!建议类似聊天室的使用Node.js来做!
pgmsoul 2013-03-29
  • 打赏
  • 举报
回复
这些代码在本地服务器运行良好, 可是在sae平台, 它把这几个关键函数都禁掉了.
pgmsoul 2013-03-29
  • 打赏
  • 举报
回复
如果是指ajax重新连接, 也是一样的, 一个ajax断开, 那个死循环也会终止, 重新开始一个页面. 数据当然要自己协调, 这里没有涉及业务. 因为持续连接, 肯定用死循环, 因为你不知道有多少数据, 顶多是添加退出条件.
pgmsoul 2013-03-29
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
先说一下代码问题: 1、你在函数中用了 document.write ,那么你的程序能正常运行吗? 2、把浏览器缓存冲掉,这一动作需在每次输出时做。你只在循环外做一次,能保证气候的数据能实时显示吗? 回到方案上: 每一次执行 ajax 都将产生一个新的 http 会话,也就是服务器每次都会执行一个php程序的副本。那么,你让被执行的php程序处于死循环中的意义……
版主啊, 你真的是版主吗? 1. 这是测试代码, document.write的确能输出啊, 哪里有问题? 明确一下. 实际上当中, 不太可能用write函数. 2. PHP代码那几行, 处理的就是这些问题, 本来PHP和浏览器都会有缓存, 这是对的, 为了提高效率一次传输数据, 效率高, 但是我们的需求就是不要这种机制, echo之后, 希望数据即时的在浏览器显示出来. ob_implicit_flush(true)和ob_flush就是起这个作用的. 但是即使如此, 浏览器自己还有缓冲, 如果数据量很小, 它会等待关闭连接后, 一次显示出来, 当然了在常规http应用中, 这种优化是非必要的, 但是现在, 也是要避免它, 所以用来3000个空格, 目的是字符足够多, 能够触发显示. 实测, 只需要第一次, 后面的数据就不需要冲了, 一个字符也会即时显示. 3. 虽然是死循环, 用户刷新之后, 页面仍然会停止, 当然, 即时通讯, 肯定要保持一个长连接. 任何语言的服务器也不可避免.

21,890

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧