Table of Contents
回复讨论(解决方案)
在线客服系统--客服端
Home Backend Development PHP Tutorial 一个iframe实现长轮询,通过PHP查询数据库并用JS更新页面内容的程序,问题是并不是每一条MYSQL的INSERT消息都能显示到页面,求帮忙分析下哪里有问题

一个iframe实现长轮询,通过PHP查询数据库并用JS更新页面内容的程序,问题是并不是每一条MYSQL的INSERT消息都能显示到页面,求帮忙分析下哪里有问题

Jun 23, 2016 pm 02:38 PM

本帖最后由 stneo1990 于 2013-08-08 11:45:06 编辑

首先,这是一个仿客服咨询的实时通讯系统,主要目的是将模拟前台用户发送的消息(通过手动INSERT进MYSQL数据库实现)由服务器实时推送到前台客服页面上,大致结构如下:
1、在前台kefu.html页面上有一个iframe,这个iframe请求后台query.php查询程序(iframe在页面上隐藏了)
2、query.php通过一个while(true)死循环并设置set_time_limit(0),然后,在循环中不断的进行SQL查询,将用户发送的未读的消息查询出来,并通过输出<script></script>JS代码,操作父页面的区,将查询出来的消息结果输出到页面上
3、我通过手动INSERT一些数据,来模拟用户的消息提交, 默认消息是未读状态,当query.php读取后,会改变其为已读状态

现在的问题是:当我打开页面后(或者关闭页面再重新打开程序),一般最开始插入的数据都不能被显示到页面上,但是这些消息的状态却已经被query.php改为已读(也就是query.php已经查询到这条记录并发送JS代码到前端了),而当我继续插入很多条之后,前端才开始显示记录,并且之前INSERT的记录都是被标记为已读状态了,但是却没有显示到前台kefu.html页面上,要插入很多条之后,或者等一段时间后才能恢复正常

整个程序并没有问题,因为之后的程序就是正常的可以一条一条显示了,插入一条前台就显示一条(但是偶尔中途也会丢失一条)

我猜测问题的根源可能有两点:
1、PHP的脚本并没有被结束
2、JS可能有缓存导致虽然接收到了数据,但没有更新

不过以上两点我都不确定,我觉得可能问题没这么简单,应该是违反或者没有注意某个机理而造成的。

具体代码如下,还请各位帮忙看看问题出在了什么地方,也可以本地测试下,谢谢了。

测试方法:
手动在数据库中INSERT数据,然后观察前台kefu.html页面是否能及时收到并更新消息

数据库建表:
CREATE TABLE msg(
id int(11) NOT NULL auto_increment,
pos varchar(20) NOT NULL default '',
rec varchar(20) NOT NULL default '',
content varchar(200) NOT NULL default '',
isread` int(1) NOT NULL default '0',
PRIMARY KEY(id)
);

插入数据示例:
insert into msg(rec,pos,content,isread) values('admin','zhangsan','hello',0);

回复讨论(解决方案)

前台kefu.html代码:

<?php  setcookie('username','admin');?><!doctype html><html>  <head>    <title>在线客服系统</title>    <meta charset="utf-8" />    <script>      //测试浏览器是Chrome 27.0.1453.93      var xhr = new XMLHttpRequest();      //由query.php程序调用的JS函数,用来输出内容到前台页面      function comet(msg,rand){        var content = '';        //获取用户发送给前台的消息,并拼接好        content = '<span onclick="reply(this);" style="cursor:pointer;">' + msg.pos + ' </span>' + '对你说:<br/>  ' + msg.content + '<br/>';        var msgzone = document.getElementById('msgzone');        //把拼接的消息赋值给消息显示区域        msgzone.innerHTML += content;      }      //点击某个用户名,然后回复的span会显示该用户名      function reply(reobj){        document.getElementById('rec').innerHTML = reobj.innerHTML      }      //前台客服回复时,调用的函数      function huifu(){        var rep = '';        //接收前台发送的用户名字        var rec = document.getElementById('rec').innerHTML;        //前台发送的消息内容        var content = document.getElementsByTagName('textarea')[0].value;        if(rec == '' || content == ''){          alert('请选择回复人并填写回复内容');//简单判断回复对象和内容不能为空          return;        }        //sendmsg.php是专门配套前台发送消息用的,就是把消息INSERT进数据库        xhr.open('POST','sendmsg.php',true);        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');        xhr.onreadystatechange = function(){          if(this.readyState == 4 && this.status == 200){            if(this.responseText == 'ok'){              //当确定前台发送的消息INSERT进数据库后,把这条消息显示到消息区域内              rep += '你对 ' + rec + '说:<br/>  ' + content + '<br/>';              var msgzone = document.getElementById('msgzone');              msgzone.innerHTML += rep;              document.getElementsByTagName('textarea')[0].value = '';            }          }        }        xhr.send('rec='+rec+'&content='+content);      }    </script>    <style>      #msgzone{        border:1px solid #ececec;        width:500px;        height:500px;        overflow:scroll;      }    </style>  </head>  <body>    <h1 id="在线客服系统-客服端">在线客服系统--客服端</h1>    <!-- 消息显示区域 -->    <div id="msgzone"></div>    <!-- 用户名区域 -->    回复:<span id="rec"></span><br/>    <!-- 回复内容区域 -->    <textarea>    </textarea><input type="button" value="回复" onclick="huifu();" />    <!-- 隐藏的iframe,其中加载了query.php来不断查询数据库是否有要推送的消息 -->    <iframe src="query.php" width="0" height="0" iframeBorder="0"></iframe>  </body></html>
Copy after login

后端查询query.php代码:

<?phpset_time_limit(0);ob_start();echo str_repeat(' ',4000),'<br/>';ob_flush();flush();$i = 0;require 'conn.php';//连接数据库文件//不断循环查询消息while(true){	//查询接收者为admin,并且是未读的消息	$sql = 'select * from msg where rec = "admin" and isread = 0 limit 1';	$result = $conn -> query($sql);	//提取查询结果	$rs = $result -> fetch_assoc();	if(!empty($rs)){		//将这条消息更新为已读状态		$sql = 'update msg set isread = 1 where id = "'.$rs['id'].'" limit 1';		$conn -> query($sql);		//转换为JSON格式准备发送给JS		$rs = json_encode($rs);		//通过paren调用父窗体的comet()函数,并将转换的JSON数据传送过去,comet()函数可以在kefu.html代码中找到		echo '<script>';		echo 'parent.window.comet(',$rs,',',mt_rand(1,1000000),')';		echo '</script>';	}	ob_flush();	flush();	//防止查询次数过多,设置的每1秒查询一次	sleep(1);}
Copy after login

数据库连接conn.php代码:

<?php	$conn = new mysqli('localhost','root','jackson613','test');	$conn -> query('set names utf8');
Copy after login

建议还是采用AJAX的轮询方式,这种的后台查询脚本里没有主动结束脚本执行,可能存在一定问题。

我测试的是只能显示一个 后面的都显示不出来

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Explain JSON Web Tokens (JWT) and their use case in PHP APIs. Apr 05, 2025 am 12:04 AM

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

Describe the SOLID principles and how they apply to PHP development. Describe the SOLID principles and how they apply to PHP development. Apr 03, 2025 am 12:04 AM

The application of SOLID principle in PHP development includes: 1. Single responsibility principle (SRP): Each class is responsible for only one function. 2. Open and close principle (OCP): Changes are achieved through extension rather than modification. 3. Lisch's Substitution Principle (LSP): Subclasses can replace base classes without affecting program accuracy. 4. Interface isolation principle (ISP): Use fine-grained interfaces to avoid dependencies and unused methods. 5. Dependency inversion principle (DIP): High and low-level modules rely on abstraction and are implemented through dependency injection.

How to automatically set permissions of unixsocket after system restart? How to automatically set permissions of unixsocket after system restart? Mar 31, 2025 pm 11:54 PM

How to automatically set the permissions of unixsocket after the system restarts. Every time the system restarts, we need to execute the following command to modify the permissions of unixsocket: sudo...

Explain the concept of late static binding in PHP. Explain the concept of late static binding in PHP. Mar 21, 2025 pm 01:33 PM

Article discusses late static binding (LSB) in PHP, introduced in PHP 5.3, allowing runtime resolution of static method calls for more flexible inheritance.Main issue: LSB vs. traditional polymorphism; LSB's practical applications and potential perfo

How to send a POST request containing JSON data using PHP's cURL library? How to send a POST request containing JSON data using PHP's cURL library? Apr 01, 2025 pm 03:12 PM

Sending JSON data using PHP's cURL library In PHP development, it is often necessary to interact with external APIs. One of the common ways is to use cURL library to send POST�...

Framework Security Features: Protecting against vulnerabilities. Framework Security Features: Protecting against vulnerabilities. Mar 28, 2025 pm 05:11 PM

Article discusses essential security features in frameworks to protect against vulnerabilities, including input validation, authentication, and regular updates.

How to debug CLI mode in PHPStorm? How to debug CLI mode in PHPStorm? Apr 01, 2025 pm 02:57 PM

How to debug CLI mode in PHPStorm? When developing with PHPStorm, sometimes we need to debug PHP in command line interface (CLI) mode...

See all articles