php开发客服系统(持久连接+轮询+反向ajax)

欢迎在php严程序 - php教程学习AJAX教程, 本节课讲解:php开发客服系统(持久连接+轮询+反向ajax)

php开发客服系统(下载源码)

用户端(可直接给客户发送消息)
客服端(点击用户名.即可给该用户回复消息)
php开发客服系统

讲两种实现方式:
一:iframe + 服务器推技术comet(反向ajax,即服务器向浏览器推送数据)
二:ajax持久连接 + 长轮询

客服端采用第一种方式:iframe + 服务器推技术
思路:
1:新建comentbyiframe.php 该用文件使用while(true)一直连接到服务器不断开.
如果在while的过程中查到了新数据.使用ob_flush推给apache服务器.apache再用flush推给浏览器.
2:新建html页面,插入一个iframe. 该iframe的src为comentbyiframe.php。
并隐藏iframe。comentbyiframe.php获取的数据用js输出到父窗口中的某个函数.该函数把信息追加到指定的聊天窗口中
3:只要客户端收到用户发来的数据. 就显示为"xx对你说..". 客服端只要点击用户名。即可给该用户发送数据.

用户端采用第二种方式:ajax持久连接 + 长轮询
ajax持久连接:文档加载完毕后(或其他时机),使用ajax请求一个php文件
被请求的php文件通过while(true)循环.迟迟不给apache返回数据的目的.
轮询指:请求服务器的时候.如果服务器没有数据.则一直等.当服务器有数据后.就返回给客户端.
这样请求、响应过后就完成了一次HTTP请求. 还没完.客户端收到数据后又到服务器要数据.这就是轮询
就好像一个乞丐一样. 不给他钱,他就一直跟着你要. 你给他钱以后.他还不满足,又跑来找你要.
实现思路:
进入用户端后.如果没有用户名.使用setcookie设置一个用户名.然后通过ajax持久连接. 不停向服务器索要数据(即客服发送给该用户的记录)

数据表设计
create table liao(
id int auto_increment primary key,
rec varchar(10) not null default '' comment '接收者',
pos varchar(10) not null default '' comment '发送者',
content varchar(30) not null default '' comment '发送内容',
isread tinyint not null default 1 comment '0已读1未读'
)engine myisam charset utf8;

客服端首页:index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title> new document </title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <script type="text/javascript" src="http://libs.baidu.com/jquery/1.8.2/jquery.min.js"></script>
  <script>
    // 将用户发来的数据写到聊天对话框中
    function write_msg(msg){
        msg = eval('('+msg+')');
        $('<p><a href="javascript:;" onclick="setRec(\''+msg.pos+'\');">'+(msg.pos)+'</a>对你说:<br />&nbsp;&nbsp;'+(msg.content)+'</p>').appendTo($('#msgzone'));
    }
    // 添加回复人
    function setRec(pos){
        $('#rec').val(pos);
        $('#comment_btn').val('回复给:'+pos);
    }
    // 回复
    function comment(){
        var rec = $('#rec').val();      // 回复给谁
        var cont = $('#cont').val();    // 回复内容
        if (rec ==''){
            alert('请先选择回复对象');
            return;
        }
        if (cont==''){
            alert('说点什么吧');
            return;        
        }
         
        $.post('comment.php',{rec:rec,cont:cont},function(msg){
            if (msg == 'ok'){
                $('<p>你对'+rec+'说:<br />'+(cont)+'</p>').appendTo($('#msgzone'));
                $('#cont').val('');
            }
        });
    }
  </script>
  <style type="text/css">
      #msgzone {width:500px; height:300px; border:1px solid #ccc; padding:10px; overflow:scroll;}
  </style>
 </head>
 <body>
  <h1>客服系统 - 客服端</h1>
  <div id="msgzone"></div>
  <iframe src="byiframe.php" width="0" height="0" frameborder="0"></iframe>
  <textarea cols="50" rows="6" id="cont"></textarea>
  <input type="button" value="回复给:" id="comment_btn" onclick="comment();" />
  <input type="hidden" id="rec" value="" />
 </body>
</html>

服务器不断推送未读记录 byiframe.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
/*
客服端
iframe + 服务器推技术 comet、反向ajax
*/
require 'conn.php';
set_time_limit(0);
ob_start();
echo str_repeat(' ',4000);
//ob_flush();
ob_end_flush();
flush();
while (true){
    // 查询用户给客服端发送的数据
    $sql 'select * from liao where isread="1" and rec="admin" order by id desc limit 1';
    $rs = mysql_query($sql,$conn);
    $row = mysql_fetch_assoc($rs);
    if ($row){
        // 将消息设置为已读
        $setRead 'update liao set isread=0 where id='.$row['id'];
        mysql_query($setRead,$conn);
        $json = json_encode($row);
        echo '<script>parent.write_msg(\''.$json.'\');</script>';
        ob_flush();     // 推给apache
        flush();        // 推给浏览器
    }
    sleep(1);
}
?>

客服给用户回复消息comment.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
/*
给用户回复消息
*/
require 'conn.php';
$rec $_POST['rec'];
$pos 'admin';
$cont $_POST['cont'];
$sql "insert into liao (rec,pos,content) values ('$rec','$pos','$cont')";
$rs = mysql_query($sql,$conn);
if ($rs){
    echo 'ok';
}
?>

持久连接,如果有信息才把信息返回给客户端.之后连接断开 getuser.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
/*
ajax调用本文件不断向服务器索要数据.如果成功后.break退出循环.
还没完,服务器返回以后.ajax再次调用继续索取
*/
if (!isset($_COOKIE['pos'])){
    exit();
}
set_time_limit(0);
require 'conn.php';
$pos = htmlspecialchars($_COOKIE['pos']);
while (true){
    $sql 'select id,content from liao where isread=1 and rec="'.$pos.'" order by id desc limit 1';
    $rs = mysql_query($sql,$conn);
    $find = mysql_fetch_assoc($rs);
    if ($find){
        $setRead 'update liao set isread=0 where id='.$find['id'];
        mysql_query($setRead,$conn);
        echo json_encode($find);
        break;
    }
     
    sleep(1);
}
?>

不让断开,用户端不断调用getuser.php索要记录 byajax.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
/*
客户端
*/
// 给该用户随机分配一个用户名
if (!isset($_COOKIE['pos'])){
    setcookie('pos','user'.mt_rand(1,100));
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <title> new document </title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <script type="text/javascript" src="http://libs.baidu.com/jquery/1.8.2/jquery.min.js"></script>
  <script>
     
    // 轮循索要数据
    $(function(){
        var setting = {
            url:'getuser.php',
            dataType:'json',
            success:function(msg){
                $('<p>客服对你说:<br />&nbsp;&nbsp;'+msg.content+'</p>').appendTo($('#msgzone'));
                // 关键:服务器返回信息以后.再去服务器索要.即:轮询
                $.ajax(setting);
            }
        }
        $.ajax(setting);
    })
    // 给客服发送数据
    function say(){
        var cont = $('#cont');
        if (cont.val() == ''){
            alert('说点什么吧');
            return;
        }
         
        $.post('toadmin.php',{content:cont.val()},function(msg){
            if (msg!=''){
                $('<p>你对客服说:<br />'+msg+'</p>').appendTo($('#msgzone'));
                cont.val('');
            }
        });
    }
  </script>
  <style type="text/css">
      #msgzone {width:500px; height:300px; border:1px solid #ccc; padding:10px; overflow:scroll;}
  </style>
 </head>
 <body>
  <h1>客服系统 - 用户端</h1>
  <div id="msgzone"></div>
  <textarea cols="50" rows="6" id="cont"></textarea>
  <input type="button" value="发送" onclick="say();" />
 </body>
</html>

用户向客服发送消息 toadmin.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
/*
向客服发送消息
*/
require 'conn.php';
if (!isset($_COOKIE['pos'])){
    exit();
}
$pos = htmlspecialchars($_COOKIE['pos']);   // 发送者
$rec 'admin';         // 接收者
$cont = htmlspecialchars($_POST['content']); // 发送内容
$sql "insert into liao (pos,rec,content) value ('$pos','$rec','$cont')";
mysql_query($sql,$conn);
echo $cont;
?>

转载于:https://www.cnblogs.com/killers888/p/5045955.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431038.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言判断整数_C语言技能|(草稿,不断完善中...)

2020年春考C语言有2个题型&#xff1a;填空&#xff0b;程序程序填空涉及&#xff1a;一、头文件的引用1.必有#include (注意&#xff1a;在devC 5.10中#include "stdio.h"也是正确的)2.若程序中使用数学函数&#xff0c;应加上头文件#include 3.头文件结尾无分号二、…

python生成器迭代_python中的生成器和迭代器

前言&#xff1a; 我们来了解一下什么是python中生成器。了解一下python生成器是什么&#xff0c;以及生成器在python编程之中能起到什么样的作用。 定义&#xff1a; 生成器和迭代器 通过列表生成式&#xff0c;我们可以直接创建一个列表。但是&#xff0c;受到内存限制&#…

python 生成pdf_如何使用Python生成PDF?

在日常办公中&#xff0c;我们会经常使用PDF文件。生成PDF的方法有很多&#xff0c;其中Python就可以。你知道怎么使用Python也可以生成PDF吗&#xff1f;下面来和小编一起学习下吧。首先我们访问网址&#xff1a;https://wkhtmltopdf.org/downloads.html &#xff0c;根据自己…

java 代码重用需要注意的事项_程序员笔记|编写高性能的Java代码需要注意的4个问题...

一、并发无法创建新的本机线程......问题1&#xff1a;Java的中创建一个线程消耗多少内存&#xff1f;每个线程有独自的栈内存&#xff0c;共享堆内存问题2&#xff1a;一台机器可以创建多少线程&#xff1f;CPU&#xff0c;内存&#xff0c;操作系统&#xff0c;JVM&#xff0…

java vbs_VBS基础篇 - vbscript Dictionary对象

Dictionary是存储数据键和项目对的对象&#xff0c;其主要属性有Count、Item、Key&#xff0c;主要方法有Add、Exists、Items、Keys、Remove、RemoveAll。创建Dictionary对象定义并创建Dictionary对象&#xff0c;使用CreateObject创建并返回自动化对象的引用Dim DicSet Dic C…

java integer最大值_五分钟学会java中的基础类型封装类

在刚刚学习java的时候&#xff0c;老师不止一次的说过java是一种面向对象的语言&#xff0c;万物皆对象。对于java中的基础数据类型&#xff0c;由于为了符合java中面向对象的特点&#xff0c;同样也有其封装类。这篇文章对其有一个认识。一、基本认识其实在jdk1.5之前&#xf…

web.xml文件位于web项目的目录结构中的_看完这篇,别人的开源项目结构应该能看懂了...

我为什么要写这篇近来&#xff0c;和不少初学Spring或Spring Boot的小伙伴私信交流了关于项目目录结构划分和代码分层的问题。很多小伙伴表示网上下载下来的开源项目看不懂&#xff0c;项目结构和代码分层看得很蒙&#xff0c;不知道应该以一个什么样的思路去学习和吸收别人的项…

mysql workbench中文设置_使用Workbench完成流体压力渗透分析

“之前的案例&#xff0c;APDL Showcase3里使用到了流体压力渗透载荷。有朋友读到以后&#xff0c;希望能在Workbench里实现这一功能。有需求就有动力&#xff0c;我们来试一试。 ”01—结果展示先看计算结果&#xff1a;(为了截图方便将模型旋转了90度)该案例为轴对称模型&…

ddns客户端_DDNS哪家最方便?试试看Mikrotik的ROS!

没有固定IP的情况下&#xff0c;想要提供外网访问&#xff0c;那么DDNS是必不可少的一个设置。DDNS&#xff08;Dynamic Domain Name Server&#xff0c;动态域名服务&#xff09;是将用户的动态IP地址映射到一个固定的域名解析服务。需要注意的是&#xff0c;不是域名是动态的…

python中级程序员是什么水准_程序员进阶:一篇搞懂Python中级应用

异常处理&#xff1a;try-except 异常即是一个事件&#xff0c;该事件会在程序执行过程中发生&#xff0c;影响了程序的正常执行。一般情况下&#xff0c;在Python无法正常处理程序时就会发生一个异常。 异常是Python对象&#xff0c;表示一个错误。当Python脚本发生异常时我们…

python做excel表格代码_[宜配屋]听图阁

安装两个库&#xff1a;pip install xlrd、pip install xlwt1.python读excel——xlrd2.python写excel——xlwt1.读excel数据&#xff0c;包括日期等数据#codingutf-8import xlrdimport datetimefrom datetime import datedef read_excel():#打开文件wb xlrd.open_workbook(rte…

python分布式框架_高性能分布式执行框架——Ray

Ray是UC Berkeley RISELab新推出的高性能分布式执行框架&#xff0c;它使用了和传统分布式计算系统不一样的架构和对分布式计算的抽象方式&#xff0c;具有比Spark更优异的计算性能。 Ray目前还处于实验室阶段&#xff0c;最新版本为0.2.2版本。虽然Ray自称是面向AI应用的分布式…

原 hibernate与mysql字段类型对应关系

原 hibernate与mysql字段类型对应关系 发表于8个月前(2015-04-17 08:56) 阅读&#xff08;1102&#xff09; | 评论&#xff08;0&#xff09; 2人收藏此文章, 我要收藏赞01月16日厦门 OSC 源创会火热报名中&#xff0c;奖品多多哦 摘要 hibernate与mysql字段类型对应关系 …

下拉选择框 其他_列表框 vs 下拉列表,哪个更好?

许多UI控件允许用户选择选项&#xff0c;它们包括复选框、单选按钮、切换开关、步进器、列表框和下拉列表。 在本文中&#xff0c;作者对列表框和下拉列表进行了定义&#xff0c;讨论何时使用各个元素&#xff0c;以及各个情况下使用哪一种更加合适。摘要列表框和下拉列表是紧凑…

springboot整合elasticsearch_Spring Boot学习10_整合Elasticsearch

一、Elasticsearch概念•以 员工文档 的形式存储为例&#xff1a;一个文档代表一个员工数据。存储数据到 ElasticSearch 的行为叫做 索引 &#xff0c;但在索引一个文档之前&#xff0c;需要确定将文档存储在哪里。•一个 ElasticSearch 集群可以 包含多个 索引 &#xff0c;相…

php制作图片轮播_图片轮播效果实现方法

图片轮播效果如何实现呢本文主要介绍了JQuery实现图片轮播效果的制作原理以及实现代码&#xff0c;文章末尾附上源码下载&#xff0c;具有很好的参考价值。下面跟着小编一起来看下吧&#xff0c;希望能帮助到大家。用JQuery操作DOM确实很方便&#xff0c;并且JQuery提供了非常人…

python有趣的面试题_一道3行代码的Python面试题,我懵逼了...|python基础教程|python入门|python教程...

https://www.xin3721.com/eschool/pythonxin3721/ 前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。 今天来说说交流群里一位群友问的Python题目。刚开始由于没有电脑&#xff0c;我也没有运行出来&…

个人应用开发详记. (三)

好久没来更新了... IM即时通讯已进入最后阶段. 各个功能模块 框架基本写好. 剩下的就是细节上的优化了 由于内容上并没有什么大幅度的变动 . 就不上图了 . 元旦回家 放假3天~ 争取年前搞定此APP 转载于:https://www.cnblogs.com/ImyFen/p/5089968.html

r语言清除变量_如何优雅地计算多变量 | R语言进阶

社会科学研究经常会遇到“超多变量”的情况——多量表、多维度、多题项&#xff0c;以及复杂的正反计分题……如何更高效地计算量表总分&#xff1f;如何更简洁地进行反向计分&#xff1f;传统的统计工具&#xff08;Excel、SPSS等&#xff09;虽然也能解决这些问题&#xff0c…

php模板初级教程,风格模板初级不完全修改教程

风格模板初级不完全修改教程更新时间&#xff1a;2006年10月09日 00:00:00 作者&#xff1a;就自己的一点点经验&#xff0c;希望能给初接触模版修改的朋友有个参考。关于模版修改&#xff0c; 引用星星签名里的一句话“学好HTML很重要” &#xff1a;)一个风格&#xff0c;…