批改状态:合格
老师批语:命名尽量不要使用拼音!注意命名规范!
<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;// 仿百度商桥客户端class Bchat extends Controller{//百度商桥首页public function index() {return view('bchat/index');}}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>仿百度商桥</title><link rel="stylesheet" href="/static/plugins/layui/css/layui.css"><script src="/static/plugins/layui/layui.js"></script></head><body><div>这是测试内容啊老弟</div></body></html><script>layui.use(['layer'], function() {var layer = layui.layer;$=layui.jquery;init_bchat();});// 百度商桥function init_bchat() {layer.open({type: 2,title: '百度商桥欢迎你',// shadeClose: true,shade: 0.2,area: ['80%', '80%'],content: '/bchat/index', //iframe的urlbtn: ['发送'],yes: function(index, layero) {var body = layer.getChildFrame('body', index);var iframeWin = window[layero.find('iframe')[0]['name']]; //得到iframe页的窗口对象,执行iframe页的方法:iframeWin.send();}});}</script>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>客户端的聊天窗口</title><link rel="stylesheet" href="/static/plugins/layui/css/layui.css"><script src="/static/plugins/layui/layui.js"></script><link rel="stylesheet" href="/static/css/bchat.css"></head><body><!-- 消息内容展示 --><div class="msg_show"></div><hr class="layui-bg-black"><!-- 消息发送区 --><div class="msg_send" contenteditable="true">请输入要发送的内容</div></body></html><script>layui.use(['layer'], function() {var layer = layui.layer;$=layui.jquery;});// 假设服务端ip为127.0.0.1ws = new WebSocket("ws://127.0.0.1:2000");ws.onopen = function() {var data={};data.type= 'login';data.group = 'member';ws.send(JSON.stringify(data));// alert("连接成功");// ws.send('tom');// alert("给服务端发送一个字符串:tom");};ws.onmessage = function(e) {var data=JSON.parse(e.data);if (data.kefu_id > 0) {var html='<div class="msg_item">\<div class="nickname">客服'+ data.kefu_id +'说:</div>\<div class="contents">'+ data.msg +'</div>\</div>';$('.msg_show').append(html);} else {var html='<div class="msg_item msg_customer">\<div class="nickname">我说:</div>\<div class="contents">'+ data.msg +'</div>\</div>';$('.msg_show').append(html);}};// <!-- 发送消息 -->function send() {var data={};data.group = 'member';data.type='msg';//发送类型是message// data.touid=1;//发给哪个客服data.msg=$('.msg_send').html();ws.send(JSON.stringify(data));$('.msg_send').html('');}</script>

<?phpnamespace App\Http\Controllers\admins;use App\Http\Controllers\Controller;use Illuminate\Http\Request;//后台客服class Kefu extends Controller{//public function index() {return view('admins/kefu/index');}}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>后台客服</title><link rel="stylesheet" href="/static/plugins/layui/css/layui.css"><script src="/static/plugins/layui/layui.js"></script><link rel="stylesheet" href="/static/css/bchat.css"></head><body><div class="kefu"><div class="kefu_title">客户接待中心</div><div class="kefu_detail"><!-- 左侧客户列表区 --><div class="member_list"></div><!-- 右侧客户对话区 --><div class="message_list"><!-- 当前的聊天内容 --><div class="message_content"></div><!-- 消息发送区域 --><div class="message_send" contenteditable="true"></div><div class="btn_send"><button class="layui-btn" onclick="sendmsg()">发送</button></div></div></div></div></body></html><script>var user_list=[];//新用户列表layui.use(['layer'], function() {var layer = layui.layer;$=layui.jquery;});// 假设服务端ip为127.0.0.1ws = new WebSocket("ws://127.0.0.1:2000");ws.onopen = function() {var data={};data.type= 'login';data.group = 'admin';ws.send(JSON.stringify(data));// alert("连接成功");// ws.send('tom');// alert("给服务端发送一个字符串:tom");};ws.onmessage = function(e) {// console.log(e.data);var data = JSON.parse(e.data);//新客户来了if (data.type==='login') {if ($.inArray(data.customer_id,user_list)===-1) {user_list.push(data.customer_id);}build_kefu_user_list();return;}// 客户连接断开if (data.type==='logout') {var index = $.inArray(data.connection_id,user_list);if (index > -1) {user_list.splice(index,1);}build_kefu_user_list();return;}var msg_member_list = $('#member_'+ data.customer_id);if (msg_member_list.length===0) {var html_container = '<div id="member_' + data.customer_id +'"></div>';$('.message_content').append(html_container);}var html='<div class="msg_item">\<div class="nickname">'+ data.customer_id +'说:</div>\<div class="contents">'+ data.msg +'</div>\</div>';$('#member_'+ data.customer_id).append(html);$('#member_'+ data.customer_id).show().siblings('div').hide();};//构建客服端的客户列表function build_kefu_user_list() {var html='';$.each(user_list,function(i,v){html+=('<div class="member_item" onclick="checkme(this)" member_id="'+v+'">客户:'+ v +'</div>');});$('.member_list').html(html);}// 和某个客户聊天function checkme(obj) {$(obj).addClass('active').siblings('div').removeClass('active');var member_id=$(obj).attr('member_id');$('#member_'+ member_id).show().siblings('div').hide();}// <!-- 发送消息 -->function sendmsg() {// 获取当前聊天的客户var touid =parseInt($('.member_list div[class*="active"]').attr('member_id'));if (isNaN(touid)) {return layer.alert('请先选择客户',{icon:2});}var data={};data.group = 'admin';data.type='msg';//发送类型是messagedata.touid=touid;//发给哪个客户data.msg=$('.message_send').html();ws.send(JSON.stringify(data));$('.message_send').html('');var html='<div class="msg_item msg_kefu">\<div class="nickname">我说:</div>\<div class="contents">'+ data.msg +'</div>\</div>';$('.message_content').append(html);}</script>

参考WebSocket即时通讯原理实战https://www.php.cn/blog/detail/22780.html
下载PHP socket即时通讯框架。
https://www.workerman.net/download/workermanzip
<?phpuse Workerman\Worker;require_once __DIR__ . '/workerman/Autoloader.php';// 注意:这里与上个例子不同,使用的是websocket协议$ws_worker = new Worker("websocket://0.0.0.0:2000");// 启动4个进程对外提供服务$ws_worker->count = 4;// 当收到客户端发来的数据后返回hello $data给客户端$ws_worker->onMessage = function($connection, $data){// 向客户端发送hello $data// $connection->send($data);// 给所有人发消息// global $ws_worker;// foreach($ws_worker->connections as $conn)// {// // $conn->send("user[{$connection->uid}] said: $data");// $conn->send($data);// }// 服务器端收到客户端的信息后返回数据给客户端var_dump($connection->id);// return;global $ws_worker;$data = json_decode($data,true);// print_r($data);// 客户端有人登录进来了if ($data['type']==='login'){// 赋值$connection->group = $data['group'];//客户登录的时候if ($data['group']==='member') {//随机分配一个客服姐姐给他$admin_list=[];foreach($ws_worker->connections as $conn) {if ($conn->group==='admin') {$admin_list[]=$conn->id;}}// 分配一个随机客服$myadmin_index = array_rand($admin_list,1);//键名$connection->touid=$admin_list[$myadmin_index];// 通知客服有新用户进来foreach($ws_worker->connections as $conn){if ($conn->id === $connection->touid) {$data['customer_id'] = $connection->id;$conn->send(json_encode($data));}}}}// 有新的消息过来了if ($data['type']==='msg'){// 赋值// 客服(管理)登录进来,发消息给用户if ($connection->group === 'admin'){$touid = $data['touid'];$msg = $data['msg'];foreach($ws_worker->connections as $conn){//向对应的用户发送消息if($touid === $conn->id) {$msgData = [];$msgData['type'] = 'msg';$msgData['kefu_id'] = $connection->id;$msgData['msg'] = $msg;$conn->send(json_encode($msgData));// 把数据储存到数据库$data = ['from_id'=>$connection->id,'to_uid'=>$touid,'msg'=>$msg];$url = 'http://laravel.edu/kefumsg/save_msg';curl_post($url,$data);// var_dump($res);}// $conn->send("user[{$connection->uid}] said: $data");}}// 客户端登录进来if ($connection->group === 'member'){// $touid=$data['touid'];foreach($ws_worker->connections as $conn){//向对应的用户发送消息if($connection->touid === $conn->id) {$data['customer_id'] = $connection->id;$conn->send(json_encode($data));// 储存数据$data = ['from_id'=>$connection->id,'to_uid'=>$connection->touid,'msg'=>$data['msg']];$url = 'http://laravel.edu/kefumsg/save_msg';curl_post($url,$data);}// $conn->send("user[{$connection->uid}] said: $data");}}}// 用户链接断开的时候$ws_worker->onClose = function($connection){// 通知客服,有人掉线了global $ws_worker;foreach($ws_worker->connections as $conn) {if ($conn->group==='admin') {$data=[];$data['type']='logout';$data['connection_id']=$connection->id;$conn->send(json_encode($data));}}};};// 定义一个http请求函数// $url 是请求的链接// $postdata 是传输的数据,数组格式function curl_post( $url, $postdata ) {$header = array('Accept: application/json',);//初始化$curl = curl_init();//设置抓取的urlcurl_setopt($curl, CURLOPT_URL, $url);//设置头文件的信息作为数据流输出curl_setopt($curl, CURLOPT_HEADER, 0);//设置获取的信息以文件流的形式返回,而不是直接输出。curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);// 超时设置curl_setopt($curl, CURLOPT_TIMEOUT, 10);// 超时设置,以毫秒为单位// curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);// 设置请求头curl_setopt($curl, CURLOPT_HTTPHEADER, $header);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE );curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE );//设置post方式提交curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);//执行命令$data = curl_exec($curl);// 显示错误信息if (curl_error($curl)) {print "Error: " . curl_error($curl);} else {// 打印返回的内容curl_close($curl);return $data;}}// 运行workerWorker::runAll();

随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号