1、tp6安装workerman扩展

 composer require topthink/think-worker

2、配置

 在config/worker_server.php下面配置worker_class

3、app目录下创建http应用并创建worker文件


worker文件源码在这里

<?php
declare (strict_types = 1);namespace app\http;use think\facade\Db;
use think\worker\Server;
use Workerman\Lib\Timer;// define('HEARTBEAT_TIME', 30);// 心跳间隔
class Worker extends Server
{protected $socket = 'websocket://0.0.0.0:2345';protected static $heartbeat_time = 50;public function onWorkerStart($worker){Timer::add(10, function()use($worker){$time_now = time();#这里统计下线人员的id$offline_user = [];foreach($worker->connections as $connection) {// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间if (empty($connection->lastMessageTime)) {$connection->lastMessageTime = $time_now;continue;}// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接// if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {if ($time_now - $connection->lastMessageTime > self::$heartbeat_time) {#这里统计下线人员的id$offline_user[] = $connection->uid;#关闭连接$connection->close();}#这里是一个用户下线后通知其他用户if (count($offline_user) > 0){$msg = ['type'=>'message','uid'=>$connection->uid,"message"=>"用户【".implode(',',$offline_user)."】下线了"];$connection->send(json_encode($msg));}}});}public function onMessage($connection,$data){#最后接收消息时间$connection->lastMessageTime = time();$msg_data = json_decode($data,true);if (!$msg_data){return;}#绑定用户IDif ($msg_data['type'] == 'bind' && !isset($connection->uid)){$connection->uid = $msg_data['uid'];$this->worker->uidConnections[$connection->uid] = $connection;}// Db::name('online_customer_service')->insert();#单人发消息if ($msg_data['type'] == 'text' && $msg_data['mode'] == 'single'){if (isset($this->worker->uidConnections[$msg_data['to_id']])){$conn = $this->worker->uidConnections[$msg_data['to_id']];$conn->send($data);}}#群聊if ($msg_data['type'] == 'text' && $msg_data['mode'] == 'group'){#实际项目通过群号查询群里有哪些用户$group_user = [10009,10010,10011,10012,10013,10014,10015,10016,10017];foreach ($group_user as $key => $val){if (isset($this->worker->uidConnections[$val])){$conn = $this->worker->uidConnections[$val];$conn->send($data);}}}// #向所有用户发送消息// foreach ($this->worker->connections as $key => $con){//    $con->send($data);// }// $connection->send(json_encode($data));// $connection->send($data);}}

4、创建chat控制器


源码在这里

<?php
/*** User BaiXiantao* Date 2022/7/4* Time 10:34*/namespace app\http\controller;use think\facade\View;class Chat
{public function index(){#聊天首页$from_id = input('from_id',10001);$to_id = 1;View::assign('from_id',$from_id);View::assign('to_id',$to_id);return View::fetch();}
}

5、在此创建index.html文件


源码在这里

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><title></title><link rel="stylesheet" type="text/css" href="/static/httpchat/font_Icon/iconfont.css"><script src="/static/admin/jquery/jquery-3.6.0.min.js"></script><style>.userlist li{background: rgb(0 0 0 / 5%);text-align: left;padding: 5px;height: 49px;/*line-height: 30px;*/font-size: 16px;border-bottom: 1px solid rgb(0 0 0 / 5%);}.userlist li img {width: 40px;height: 40px;padding-right: 5px;}.message-num{right: 2px;}.ChatInfoName{height: 50px;border-bottom: 1px solid #D9D9D9;line-height: 50px;font-size: 16px;padding: 0 10px;}.chatBox-content{height: 498px !important;width: 100%;}.chatBox-content-demo{width: 100%;height: 370px !important;overflow-y: scroll;}.div-textarea{width: 490px !important;/*min-height: 20px;*/height: 100px;_height: 120px;padding: 3px;outline: 0;background: #fff;font-size: 14px;line-height: 20px;word-wrap: break-word;overflow-x: hidden;overflow-y: auto;user-modify: read-write-plaintext-only;    /*纯文本*/-webkit-user-modify: read-write-plaintext-only;-moz-user-modify: read-write-plaintext-only;}.div-textarea:focus{box-shadow: 0 0 15px rgba(82, 168, 236, 0.6);}.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}.clearfloat{zoom:1;margin: 10px 10px;}.clearfloat .right{float: right;}.author-name{text-align: center;margin: 15px 0 5px 0;color: #888;}.clearfloat .chat-message{max-width: 252px;text-align: left;padding: 8px 12px;border-radius: 6px;word-wrap:break-word;display: inline-block;position: relative;}.clearfloat .left .chat-message{background: #D9D9D9;min-height: 36px;}.clearfloat .left .chat-message:before{position: absolute;content: "";top: 8px;left: -6px;border-top: 10px solid transparent;border-bottom: 10px solid transparent;border-right: 10px solid #D9D9D9;}.clearfloat .right{text-align: right;}.clearfloat .right .chat-message{background: #8c85e6;color: #fff;text-align: left;min-height: 36px;}.clearfloat .right .chat-message:before{position: absolute;content: "";top: 8px;right: -6px;border-top: 10px solid transparent;border-bottom: 10px solid transparent;border-left: 10px solid #8c85e6;}.clearfloat .chat-avatars{display: inline-block;width: 30px;height: 30px;border-radius: 50%;background: #eee;vertical-align: top;overflow: hidden;}.clearfloat .chat-avatars>img{width: 30px;height: 30px;}.clearfloat .left .chat-avatars{margin-right: 10px;}.clearfloat .right .chat-avatars{margin-left: 10px;}.chatBox-send{width: 100%;padding: 10px 5px;background: #eee;border-top: 1px #D0D0D0 solid;position: absolute;bottom: 0;left: 0;}.chatBox-send>div{float: left;}.chatBox-send>div:nth-of-type(2){font-size: 0;}.chatBox-send>div button{padding: 1px 5px;margin-left: 3px;}.chatBox-send>div label{padding: 1px 5px;margin-left: 3px;}#chat-biaoqing{position: relative;}.hidden{display: none;}.biaoqing-photo{width: 200px;height: 160px;background: #ffffff;position: absolute;top: -160px;right: 40px;text-align: left;border-radius: 5px;border: solid 1px #c5c5c5;display: none;}.biaoqing-photo::before{content: '';position: absolute;border-top: solid 7px #c5c5c5;border-left: solid 9px transparent;border-right: solid 9px transparent;bottom: -7px;right: 36px;}.biaoqing-photo::after{content: '';position: absolute;border-top: solid 7px #fff;border-left: solid 10px transparent;border-right: solid 10px transparent;bottom: -5px;right: 35px;}.biaoqing-photo>ul{margin: 0;width: 200px;height: 160px;padding: 3px 2px;list-style: none;}.biaoqing-photo>ul>li{float: left;height: 30px;margin-left: 2px;}.emoji-picker-image{display: inline-block;width: 30px;height: 30px;background: url(/static/httpchat/img/bqxtb01.png) no-repeat;background-size: 200px auto;cursor: pointer;}.biaoqing-photo>ul>li span.emoji-picker-image:hover{border: solid 1px #f5f5f5;}.chat-message img{width: 220px;height:auto;}.chat-name{width: 230px;}/*按钮样式*/.btn-default-styles {outline: none;resize: none;border: none;display: inline-block;padding: 5px 10px;margin-bottom: 0;font-size: 14px;font-weight: 400;line-height: 1.42857143;text-align: center;white-space: nowrap;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;background-image: none;background: #bbb;color: #fff;border-radius: 4px;}.btn-default-styles:focus {outline: none;}.btn-default-styles:hover {background: #c5c5c5;animation: anniu 1s infinite;}.btn-default-styles:active {box-shadow: 0 2px 3px rgba(0, 0, 0, .2) inset;}/* 设置滚动条的样式 */::-webkit-scrollbar {width:5px;}/* 滚动槽 */::-webkit-scrollbar-track {border-radius:10px;}/* 滚动条滑块 */::-webkit-scrollbar-thumb {border-radius:10px;background:#8C85E6;-webkit-box-shadow:#8C85E6;}::-webkit-scrollbar-thumb:window-inactive {background: rgba(175, 190, 255, 0.4);}@media all and (max-width: 768px) {.chatBox{position: fixed;top: 0;left: 0;width: 100%;height: 100%;}}@media all and (max-width: 370px){.chat-name{width: 185px;}.chat-people>div:nth-of-type(2){width: 120px;}.clearfloat .chat-message{max-width: 240px;}}</style>
</head>
<body>
<div class="layui-fluid" style="padding: 0"><div class="layui-row" style="overflow: hidden;"><div class="layui-col-md3 layui-col-lg3 layui-col-xs3 div-user" style="border-right: 1px solid #b4b2b2;height: 549px;overflow-y: scroll;"><ul class="userlist" id="chatuser"><li lay-id="1"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">管理员</span><span class="message-num">20</span></li></ul></div><div class="layui-col-md9 layui-col-lg9 layui-col-xs9 "><div id="chatcontent"><div class="ChatInfoName">这里是用户昵称</div><div><div class="chatBox-content"><div class="chatBox-content-demo" id="chatBox-content-demo"></div></div><div class="chatBox-send"><div class="div-textarea" contenteditable="true"></div><div><button id="chat-biaoqing" class="btn-default-styles"><i class="iconfont icon-biaoqing"></i></button><label id="chat-tuxiang" title="发送图片" for="inputImage" class="btn-default-styles"><input type="file" onchange="selectImg(this)" accept="image/jpg,image/jpeg,image/png"name="file" id="inputImage" class="hidden"><i class="iconfont icon-tuxiang"></i></label><button id="chat-fasong" class="btn-default-styles"><i class="iconfont icon-fasong"></i></button></div><div class="biaoqing-photo"><ul><li><span class="emoji-picker-image" style="background-position: -9px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -154px;"></span></li></ul></div></div></div></div></div></div>
</div><!--<div class="layui-fluid">-->
<!--    ……-->
<!--</div>--></body>
</html>
<script>var myavatars = '';var myDate =new Date();var year=myDate.getFullYear(); //获取当前年份var mon=myDate.getMonth()+1; //获取当前月份var da=myDate.getDate(); //获取当前日var day=myDate.getDay(); //获取当前星期几var h=myDate.getHours(); //获取小时var m=myDate.getMinutes(); //获取分钟var s=myDate.getSeconds(); //获取秒var ms=myDate.getMilliseconds();   //获取当前毫秒数(0-999)var ld=myDate.toLocaleDateString();   //获取当前日期var msgdate=year+'-'+mon+'-'+da+' '+h+':'+m+':'+s;var from_id = "{$from_id}";var to_id = "{$to_id}";//进聊天页面$("#chatuser li").each(function () {$(this).click(function () {$("#chatuser li").css('background','rgb(0 0 0 / 5%)')$(this).css('background','#ffffff')var n = $(this).index();to_id = $(this).attr('lay-id')// $(".chatBox-head-one").toggle();// $(".chatBox-head-two").toggle();// $(".chatBox-list").fadeToggle();// $(".chatBox-kuang").fadeToggle();//传名字$(".ChatInfoName").text($(this).children(".chat-name").eq(0).html());//赋值头像myavatars = $(this).children('img').eq(0).attr("src");// //传头像//聊天框默认最底部$(document).ready(function () {$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);});// // 打开websocket// webSocket.onopen = function (event) {onOpen();// };})});// var userlist = [10009,10010,10011,10012,10013,10014,10015,10016,10017];/**0:未连接1:连接成功,可通讯2:正在关闭3:连接已关闭或无法打开*///创建一个webSocket 实例var webSocket = new WebSocket("ws://192.168.0.113:2345");webSocket.onerror = function (event) {onError(event);};// 打开websocketwebSocket.onopen = function (event) {onOpen(event);};//监听消息webSocket.onmessage = function (event) {onMessage(event);};webSocket.onclose = function (event) {onClose(event);}//关闭监听websocketfunction onError(event) {// document.getElementById("msg").innerHTML = "<p>关闭</p>";console.log("错误: " + event.data);}function onOpen(event) {// console.log("打开: "+sockState());var bild = '{"type":"bind","uid":"' + from_id + '"}';webSocket.send(bild);setInterval(function () {webSocket.send('heartbeat');    //发送内容不限,只是为了证明客户端还没关闭还在线}, 20000)                    //50秒发一次}function onMessage(event) {// console.log(event.data)var massage = eval("(" + event.data + ")");//这里表示一对一聊天if (massage.type == 'text' && massage.mode == 'single') {//当前正在聊天的人  如果当前的发送对象id等于该消息来源的id,则为一个人  ,if (this.to_id == massage.from_id) {// console.log("服务端消息:"+massage.content);// $("#chatBox-content-demo").append("<div>我是" + massage.from_id + ":" + massage.content + "</div>");$("#chatBox-content-demo").append("<div class=\"clearfloat\">\n" +"                                <div class=\"author-name\">\n" +"                                    <small class=\"chat-date\">"+ massage.datetime +"</small>\n" +"                                </div>\n" +"                                <div class=\"left\">\n" +"                                    <div class=\"chat-avatars\"><img src=\"" + myavatars + "\" alt=\"头像\"/></div>\n" +"                                    <div class=\"chat-message\">" + massage.content + "</div>\n" +"                                </div>\n" +"                            </div>");return;} else {//不是当前聊天的人、将消息提醒发送到对应的列表,并将消息发送到对应页面//在数据库请求该人的基本信息,}}//这里表示群聊if (massage.type == 'text' && massage.mode == 'group') {console.log(massage);}}function onClose(event) {// document.getElementById("msg").innerHTML = "<p>他通讯已关闭</p>";console.log("关闭: " + sockState());webSocket.close();}function sockState() {var status = ['未连接', '连接成功,可通讯', '正在关闭', '连接已关闭或无法打开'];return status[webSocket.readyState];}function close(event) {webSocket.close();}document.onkeydown = keyDownSearch;function keyDownSearch(e) {// 兼容FF和IE和Operavar theEvent = e || window.event;var code = theEvent.keyCode || theEvent.which || theEvent.charCode;if (code == 13) {//具体处理函数chat_fasong()return false;}return true;}//未读信息数量为空时var totalNum = $(".chat-message-num").html();if (totalNum == "") {$(".chat-message-num").css("padding", 0);}$(".message-num").each(function () {var wdNum = $(this).html();if (wdNum == "") {$(this).css("padding", 0);}});//      发送信息$("#chat-fasong").click(function () {chat_fasong()});function chat_fasong() {var textContent = $(".div-textarea").html().replace(/[\n\r]/g, '<br>')if (textContent != "") {//发送到服务器var msg1 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + textContent + '","datetime":"' + msgdate + '"}';webSocket.send(msg1);$(".chatBox-content-demo").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">" + msgdate + "</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"> " + textContent + " </div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");/*"/static/httpchat/img/icon01.png"*///发送后清空输入框$(".div-textarea").html("");//聊天框默认最底部$(document).ready(function () {$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);});}}//      发送表情$("#chat-biaoqing").click(function () {$(".biaoqing-photo").toggle();});$(document).click(function () {$(".biaoqing-photo").css("display", "none");});$("#chat-biaoqing").click(function (event) {event.stopPropagation();//阻止事件});$(".emoji-picker-image").each(function () {$(this).click(function () {var bq = $(this).parent().html();//发送到服务器var msg2 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + bq + '","datetime":"' + msgdate + '"}';webSocket.send(msg2);$(".chatBox-content-demo").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">"+ msgdate +"</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"> " + bq + " </div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");//发送后关闭表情框$(".biaoqing-photo").toggle();//聊天框默认最底部$(document).ready(function () {$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);});})});//      发送图片function selectImg(pic) {if (!pic.files || !pic.files[0]) {return;}var reader = new FileReader();reader.onload = function (evt) {var images = evt.target.result;var to_img = "<img src=" + images + ">";//发送到服务器var msg3 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + to_img + '","datetime":"' + msgdate + '"}';webSocket.send(msg3);$(".chatBox-content-demo").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">"+ msgdate +"</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"><img src=" + images + "></div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");//聊天框默认最底部$(document).ready(function () {$("#chatBox-content-demo").scrollTop($("#chatBox-content-demo")[0].scrollHeight);});};reader.readAsDataURL(pic.files[0]);}</script>

iconfont.css文件源码


@font-face {font-family: "iconfont";src: url('iconfont.eot?t=1515469903495'); /* IE9*/src: url('iconfont.eot?t=1515469903495#iefix') format('embedded-opentype'), /* IE6-IE8 */url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),url('iconfont.ttf?t=1515469903495') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/url('iconfont.svg?t=1515469903495#iconfont') format('svg'); /* iOS 4.1- */
}.iconfont {font-family:"iconfont" !important;font-size:16px;font-style:normal;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;
}.icon-gouwuche2:before { content: "\e610"; }.icon-verylarger-view:before { content: "\e622"; }.icon-tehui:before { content: "\e60c"; }.icon-gengduo1:before { content: "\e606"; }.icon-xiaoxi:before { content: "\e609"; }.icon-houtui:before { content: "\e607"; }.icon-gouwuche:before { content: "\e60d"; }.icon-guojia:before { content: "\e6c0"; }.icon-xiaoxi1:before { content: "\e62d"; }.icon-shoucang:before { content: "\e60f"; }.icon-tuxiang:before { content: "\e645"; }.icon-yushou:before { content: "\e644"; }.icon-icon05:before { content: "\e630"; }.icon-jiadian:before { content: "\e670"; }.icon-shoucang1:before { content: "\e6a2"; }.icon-dingdan:before { content: "\e682"; }.icon-shuaxin:before { content: "\e6fc"; }.icon-kefu:before { content: "\e6df"; }.icon-shoucang2:before { content: "\e71a"; }.icon-wode2:before { content: "\e6f3"; }.icon-gengduo:before { content: "\e617"; }.icon-larger-view:before { content: "\e655"; }.icon-tuxiang1:before { content: "\e63d"; }.icon-geren2-copy:before { content: "\e657"; }.icon-jiushui:before { content: "\e61b"; }.icon-shuji:before { content: "\e61e"; }.icon-fasong:before { content: "\e625"; }.icon-xuanzhuan:before { content: "\e614"; }.icon-shouye:before { content: "\e60e"; }.icon-guanbi:before { content: "\e72c"; }.icon-wode:before { content: "\e61d"; }.icon-app:before { content: "\e62c"; }.icon-fanhui:before { content: "\e6d6"; }.icon-guanbi1:before { content: "\e705"; }.icon-yingyangbaojian:before { content: "\e639"; }.icon-fenlei:before { content: "\e60a"; }.icon-xiaoxi2:before { content: "\e69a"; }.icon-shanchu:before { content: "\e642"; }.icon-qian:before { content: "\e624"; }.icon-shoucangjia:before { content: "\e618"; }.icon-meishi:before { content: "\e7af"; }.icon-larger-view2:before { content: "\e627"; }.icon-dingbu:before { content: "\e67d"; }.icon-pingjia:before { content: "\e619"; }.icon-xiaoxi3:before { content: "\e61a"; }.icon-wode1:before { content: "\e621"; }.icon-wode4:before { content: "\e611"; }.icon-yingerfeng:before { content: "\e620"; }.icon-xiaoxi4:before { content: "\e623"; }.icon-xiaoxi5:before { content: "\e67e"; }.icon-ccgl-shouhuoguanli-3:before { content: "\e601"; }.icon-liwu_gift:before { content: "\e604"; }.icon-shoucang3:before { content: "\e613"; }.icon-jiaju:before { content: "\e65d"; }.icon-shoucang4:before { content: "\e602"; }.icon-sousuo2:before { content: "\e61c"; }.icon-biaoqing:before { content: "\e605"; }.icon-kouhong:before { content: "\e60b"; }.icon-gengduo2:before { content: "\e728"; }.icon-gift:before { content: "\e600"; }.icon-lingquan:before { content: "\e61f"; }.icon-jifen:before { content: "\e674"; }.icon-qianjin:before { content: "\e608"; }.icon-shoucang11:before { content: "\e603"; }.icon-shuaxin1:before { content: "\e626"; }.icon-zhongxin:before { content: "\e650"; }.icon-list-view:before { content: "\e628"; }.icon-fushi:before { content: "\e63c"; }.icon-saoyisao:before { content: "\e612"; }.icon-double-vertical:before { content: "\e615"; }.icon-up-down:before { content: "\e66f"; }.icon-sousuo1:before { content: "\e66e"; }.icon-double-cross:before { content: "\e616"; }.icon-left-right:before { content: "\e7b0"; }

6、到这里,前台人员给后台人员发消息的框框就出来了,可以在任何地方调用前台代码,接下来我们看后台管理人员的代码

控制器

<?php
/*** User BaiXiantao* Date 2022/7/4* Time 14:00*/namespace app\admin\controller;use think\facade\View;class Chat extends Common
{public function index(){$from_id = 1;  //将这里的formid为1,表示管理员$to_id = 1;View::assign('from_id',$from_id);View::assign('to_id',$to_id);return View::fetch();}
}

html文件

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><title></title><link rel="stylesheet" href="/static/admin/layui272/css/layui.css" media="all"><!--    <link rel="stylesheet" type="text/css" href="/static/httpchat/css/chat.css">--><link rel="stylesheet" type="text/css" href="/static/httpchat/font_Icon/iconfont.css"><script src="/static/admin/jquery/jquery-3.6.0.min.js"></script><style>.userlist li{background: rgb(0 0 0 / 5%);text-align: left;padding: 5px;height: 49px;/*line-height: 30px;*/font-size: 16px;border-bottom: 1px solid rgb(0 0 0 / 5%);}.userlist li img {width: 40px;height: 40px;padding-right: 5px;}.message-num{/*right: 2px;*//*padding: 4px;*/color: red;/*background: red;*//*position: relative;*//*margin-left: -20px;*//*top: -15px;*//*width: 5px;*//*height: 5px;*//*border-radius: 10px;*/}.ChatInfoName{height: 50px;border-bottom: 1px solid #D9D9D9;line-height: 50px;font-size: 16px;padding: 0 10px;}.chatBox-content{height: 498px !important;width: 100%;}.chatBox-content-demo{width: 100%;height: 370px !important;overflow-y: scroll;}.div-textarea{width: 490px !important;/*min-height: 20px;*/height: 100px;_height: 120px;padding: 3px;outline: 0;background: #fff;font-size: 14px;line-height: 20px;word-wrap: break-word;overflow-x: hidden;overflow-y: auto;user-modify: read-write-plaintext-only;    /*纯文本*/-webkit-user-modify: read-write-plaintext-only;-moz-user-modify: read-write-plaintext-only;}.div-textarea:focus{box-shadow: 0 0 15px rgba(82, 168, 236, 0.6);}.clearfloat:after{display:block;clear:both;content:"";visibility:hidden;height:0}.clearfloat{zoom:1;margin: 10px 10px;}.clearfloat .right{float: right;}.author-name{text-align: center;margin: 15px 0 5px 0;color: #888;}.clearfloat .chat-message{max-width: 252px;text-align: left;padding: 8px 12px;border-radius: 6px;word-wrap:break-word;display: inline-block;position: relative;}.clearfloat .left .chat-message{background: #D9D9D9;min-height: 36px;}.clearfloat .left .chat-message:before{position: absolute;content: "";top: 8px;left: -6px;border-top: 10px solid transparent;border-bottom: 10px solid transparent;border-right: 10px solid #D9D9D9;}.clearfloat .right{text-align: right;}.clearfloat .right .chat-message{background: #8c85e6;color: #fff;text-align: left;min-height: 36px;}.clearfloat .right .chat-message:before{position: absolute;content: "";top: 8px;right: -6px;border-top: 10px solid transparent;border-bottom: 10px solid transparent;border-left: 10px solid #8c85e6;}.clearfloat .chat-avatars{display: inline-block;width: 30px;height: 30px;border-radius: 50%;background: #eee;vertical-align: top;overflow: hidden;}.clearfloat .chat-avatars>img{width: 30px;height: 30px;}.clearfloat .left .chat-avatars{margin-right: 10px;}.clearfloat .right .chat-avatars{margin-left: 10px;}.chatBox-send{width: 100%;padding: 10px 5px;background: #eee;border-top: 1px #D0D0D0 solid;position: absolute;bottom: 0;left: 0;}.chatBox-send>div{float: left;}.chatBox-send>div:nth-of-type(2){font-size: 0;}.chatBox-send>div button{padding: 1px 5px;margin-left: 3px;}.chatBox-send>div label{padding: 1px 5px;margin-left: 3px;}#chat-biaoqing{position: relative;}.hidden{display: none;}.biaoqing-photo{width: 200px;height: 160px;background: #ffffff;position: absolute;top: -160px;right: 40px;text-align: left;border-radius: 5px;border: solid 1px #c5c5c5;display: none;}.biaoqing-photo::before{content: '';position: absolute;border-top: solid 7px #c5c5c5;border-left: solid 9px transparent;border-right: solid 9px transparent;bottom: -7px;right: 36px;}.biaoqing-photo::after{content: '';position: absolute;border-top: solid 7px #fff;border-left: solid 10px transparent;border-right: solid 10px transparent;bottom: -5px;right: 35px;}.biaoqing-photo>ul{margin: 0;width: 200px;height: 160px;padding: 3px 2px;list-style: none;}.biaoqing-photo>ul>li{float: left;height: 30px;margin-left: 2px;}.emoji-picker-image{display: inline-block;width: 30px;height: 30px;background: url(/static/httpchat/img/bqxtb01.png) no-repeat;background-size: 200px auto;cursor: pointer;}.biaoqing-photo>ul>li span.emoji-picker-image:hover{border: solid 1px #f5f5f5;}.chat-message img{width: 220px;height:auto;}.chat-name{width: 230px;}/*按钮样式*/.btn-default-styles {outline: none;resize: none;border: none;display: inline-block;padding: 5px 10px;margin-bottom: 0;font-size: 14px;font-weight: 400;line-height: 1.42857143;text-align: center;white-space: nowrap;vertical-align: middle;-ms-touch-action: manipulation;touch-action: manipulation;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;background-image: none;background: #bbb;color: #fff;border-radius: 4px;}.btn-default-styles:focus {outline: none;}.btn-default-styles:hover {background: #c5c5c5;animation: anniu 1s infinite;}.btn-default-styles:active {box-shadow: 0 2px 3px rgba(0, 0, 0, .2) inset;}/* 设置滚动条的样式 */::-webkit-scrollbar {width:5px;}/* 滚动槽 */::-webkit-scrollbar-track {border-radius:10px;}/* 滚动条滑块 */::-webkit-scrollbar-thumb {border-radius:10px;background:#8C85E6;-webkit-box-shadow:#8C85E6;}::-webkit-scrollbar-thumb:window-inactive {background: rgba(175, 190, 255, 0.4);}@media all and (max-width: 768px) {.chatBox{position: fixed;top: 0;left: 0;width: 100%;height: 100%;}}@media all and (max-width: 370px){.chat-name{width: 185px;}.chat-people>div:nth-of-type(2){width: 120px;}.clearfloat .chat-message{max-width: 240px;}}</style>
</head>
<body>
<div class="layui-fluid" style="padding: 0"><div class="layui-row" style="overflow: hidden;"><div class="layui-col-md3 layui-col-lg3 layui-col-xs3 div-user" style="border-right: 1px solid #b4b2b2;height: 549px;overflow-y: scroll;"><ul class="userlist" id="chatuser"><li id="10001"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10001</span><span class="message-num"></span></li><li id="10002"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10002</span><span class="message-num"></span></li><li id="10003"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10003</span><span class="message-num"></span></li><li id="10004"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10004</span><span class="message-num"></span></li><li id="10005"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10005</span><span class="message-num"></span></li><li id="10006"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10006</span><span class="message-num"></span></li><li id="10007"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10007</span><span class="message-num"></span></li><li id="10008"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10008</span><span class="message-num"></span></li><li id="10009"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10009</span><span class="message-num"></span></li><li id="10010"><img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" alt=""><span class="chat-name">用户10010</span><span class="message-num"></span></li></ul></div><div class="layui-col-md9 layui-col-lg9 layui-col-xs9 "><div id="chatcontent"><div class="ChatInfoName">这里是用户昵称</div><div><div class="chatBox-content"><div class="chatBox-content-demo chatBox-content-demo_1" id="chatBox-content-demo"><!--这里是消息内容------没有更多消息--></div></div><div class="chatBox-send"><div class="div-textarea" contenteditable="true"></div><div><button id="chat-biaoqing" class="btn-default-styles"><i class="iconfont icon-biaoqing"></i></button><label id="chat-tuxiang" title="发送图片" for="inputImage" class="btn-default-styles"><input type="file" onchange="selectImg(this)" accept="image/jpg,image/jpeg,image/png"name="file" id="inputImage" class="hidden"><i class="iconfont icon-tuxiang"></i></label><button id="chat-fasong" class="btn-default-styles"><i class="iconfont icon-fasong"></i></button></div><div class="biaoqing-photo"><ul><li><span class="emoji-picker-image" style="background-position: -9px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -18px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -52px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -86px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -120px;"></span></li><li><span class="emoji-picker-image" style="background-position: -9px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -40px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -71px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -102px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -133px -154px;"></span></li><li><span class="emoji-picker-image" style="background-position: -164px -154px;"></span></li></ul></div></div></div></div></div></div>
</div></body>
</html>
<script>var myavatars = '';var myDate =new Date();var year=myDate.getFullYear(); //获取当前年份var mon=myDate.getMonth()+1; //获取当前月份var da=myDate.getDate(); //获取当前日var day=myDate.getDay(); //获取当前星期几var h=myDate.getHours(); //获取小时var m=myDate.getMinutes(); //获取分钟var s=myDate.getSeconds(); //获取秒var ms=myDate.getMilliseconds();   //获取当前毫秒数(0-999)var ld=myDate.toLocaleDateString();   //获取当前日期var msgdate=year+'-'+mon+'-'+da+' '+h+':'+m+':'+s;var from_id = "{$from_id}";var to_id = "{$to_id}";//进聊天页面$("#chatuser li").each(function () {$(this).on('click',function () {$("#chatuser li").css('background','rgb(0 0 0 / 5%)')$(this).css('background','#ffffff')$(".chatBox-content-demo").css('display','none');var n = $(this).index();to_id = $(this).attr('id')//如果这个id不存在,就添加这个idif ($("#chatBox-content_"+to_id+"").length == 0){console.log($("#chatBox-content_"+to_id+"").length)//插入新的div$(".chatBox-content").append("<div class='chatBox-content-demo' id='chatBox-content_"+to_id+"'></div>");}$("#chatBox-content_"+to_id+"").css('display','block');$("#"+to_id+" .message-num").text('');// $(".chatBox-head-one").toggle();// $(".chatBox-head-two").toggle();// $(".chatBox-list").fadeToggle();// $(".chatBox-kuang").fadeToggle();//传名字$(".ChatInfoName").text($(this).children(".chat-name").eq(0).html());//赋值头像myavatars = $(this).children('img').eq(0).attr("src");//聊天框默认最底部$(document).ready(function () {$(".chatBox-content-demo").scrollTop($(".chatBox-content-demo")[0].scrollHeight);});// 打开websocketonOpen();})});// var userlist = [10009,10010,10011,10012,10013,10014,10015,10016,10017];/**0:未连接1:连接成功,可通讯2:正在关闭3:连接已关闭或无法打开*///创建一个webSocket 实例var webSocket = new WebSocket("ws://192.168.0.113:2345");webSocket.onerror = function (event) {onError(event);};// 打开websocketwebSocket.onopen = function (event) {onOpen(event);};//监听消息webSocket.onmessage = function (event) {onMessage(event);};webSocket.onclose = function (event) {onClose(event);}//关闭监听websocketfunction onError(event) {console.log("错误: " + event.data);}function onOpen(event) {// console.log("打开: "+sockState());var bild = '{"type":"bind","uid":"' + from_id + '"}';webSocket.send(bild);// console.log("已发送绑定: "+bild);// webSocket.send(JSON.stringify(bild));// document.getElementById("msg").innerHTML = "<p>连接到服务</p>";setInterval(function () {webSocket.send('heartbeat');    //发送内容不限,只是为了证明客户端还没关闭还在线}, 30000)                    //50秒发一次}function onMessage(event) {// console.log(event.data)var massage = eval("(" + event.data + ")");//这里表示一对一聊天if (massage.type == 'text' && massage.mode == 'single') {//当前正在聊天的人  如果当前的发送对象id等于该消息来源的id,则为一个人  ,if (this.to_id == massage.from_id) {console.log("服务端消息:"+massage.content);$("#chatBox-content_"+to_id+"").append("<div class=\"clearfloat\">\n" +"                                <div class=\"author-name\">\n" +"                                    <small class=\"chat-date\">"+ massage.datetime +"</small>\n" +"                                </div>\n" +"                                <div class=\"left\">\n" +"                                    <div class=\"chat-avatars\"><img src=\"" + myavatars + "\" alt=\"头像\"/></div>\n" +"                                    <div class=\"chat-message\">" + massage.content + "</div>\n" +"                                </div>\n" +"                            </div>");return;} else {//不是当前聊天的人、将消息提醒发送到对应的列表,并将消息发送到对应页面//在数据库请求该人的基本信息,if ($("#chatBox-content_"+massage.from_id+"").length == 0){console.log($("#chatBox-content_"+massage.from_id+"").length)//插入新的div$(".chatBox-content").append("<div class='chatBox-content-demo' id='chatBox-content_"+massage.from_id+"' style='display: none;'></div>");}$("#chatBox-content_"+massage.from_id+"").append("<div class=\"clearfloat\">\n" +"                                <div class=\"author-name\">\n" +"                                    <small class=\"chat-date\">"+ massage.datetime +"</small>\n" +"                                </div>\n" +"                                <div class=\"left\">\n" +"                                    <div class=\"chat-avatars\"><img src=\"" + myavatars + "\" alt=\"头像\"/></div>\n" +"                                    <div class=\"chat-message\">" + massage.content + "</div>\n" +"                                </div>\n" +"                            </div>");// var this_message_num = parseInt($("#"+massage.from_id+" message-num").text());var this_message_num = Number($("#"+massage.from_id+" .message-num").text()) + 1;console.log(this_message_num);$("#"+massage.from_id+" .message-num").text(this_message_num);return;}}//这里表示群聊if (massage.type == 'text' && massage.mode == 'group') {console.log(massage);}//消息通知--用户下线消息通知等if (massage.type == "message"){console.log(massage.message);}}function onClose(event) {// document.getElementById("msg").innerHTML = "<p>他通讯已关闭</p>";console.log("关闭: " + sockState());webSocket.close();}function sockState() {var status = ['未连接', '连接成功,可通讯', '正在关闭', '连接已关闭或无法打开'];return status[webSocket.readyState];}function close(event) {webSocket.close();}document.onkeydown = keyDownSearch;function keyDownSearch(e) {// 兼容FF和IE和Operavar theEvent = e || window.event;var code = theEvent.keyCode || theEvent.which || theEvent.charCode;if (code == 13) {//具体处理函数chat_fasong()return false;}return true;}//未读信息数量为空时var totalNum = $(".chat-message-num").html();if (totalNum == "") {$(".chat-message-num").css("padding", 0);}$(".message-num").each(function () {var wdNum = $(this).html();if (wdNum == "") {$(this).css("padding", 0);}});//      发送信息$("#chat-fasong").click(function () {chat_fasong()});function chat_fasong() {var textContent = $(".div-textarea").html().replace(/[\n\r]/g, '<br>')if (textContent != "") {//发送到服务器var msg1 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + textContent + '","datetime":"' + msgdate + '"}';webSocket.send(msg1);$("#chatBox-content_"+to_id+"").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">" + msgdate + "</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"> " + textContent + " </div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");/*"/static/httpchat/img/icon01.png"*///发送后清空输入框$(".div-textarea").html("");//聊天框默认最底部$(document).ready(function () {$(".chatBox-content-demo").scrollTop($(".chatBox-content-demo")[0].scrollHeight);});}}//      发送表情$("#chat-biaoqing").click(function () {$(".biaoqing-photo").toggle();});$(document).click(function () {$(".biaoqing-photo").css("display", "none");});$("#chat-biaoqing").click(function (event) {event.stopPropagation();//阻止事件});$(".emoji-picker-image").each(function () {$(this).click(function () {var bq = $(this).parent().html();//发送到服务器var msg2 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + bq + '","datetime":"' + msgdate + '"}';webSocket.send(msg2);$("#chatBox-content_"+to_id+"").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">"+ msgdate +"</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"> " + bq + " </div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");//发送后关闭表情框$(".biaoqing-photo").toggle();//聊天框默认最底部$(document).ready(function () {$(".chatBox-content-demo").scrollTop($(".chatBox-content-demo")[0].scrollHeight);});})});//      发送图片function selectImg(pic) {if (!pic.files || !pic.files[0]) {return;}var reader = new FileReader();reader.onload = function (evt) {var images = evt.target.result;var to_img = "<img src=" + images + ">";//发送到服务器var msg3 = '{"type":"text","mode":"single","from_id":"' + from_id + '","to_id":"' + to_id + '","content":"' + to_img + '","datetime":"' + msgdate + '"}';webSocket.send(msg3);$("#chatBox-content_"+to_id+"").append("<div class=\"clearfloat\">" +"<div class=\"author-name\"><small class=\"chat-date\">"+ msgdate +"</small> </div> " +"<div class=\"right\"> <div class=\"chat-message\"><img src=" + images + "></div> " +"<div class=\"chat-avatars\"><img src=\"/static/httpchat/img/icon01.png\" alt=\"头像\" /></div> </div> </div>");//聊天框默认最底部$(document).ready(function () {$(".chatBox-content-demo").scrollTop($(".chatBox-content-demo")[0].scrollHeight);});};reader.readAsDataURL(pic.files[0]);}</script>

至此,聊天逻辑和页面基本完成,后续的一些聊天聊天记录的存储等,可使用 redis 完成,(客服基本上不需要保存啥消息),里面的一些东西可根据自己的需求完善

php在线客服:TP6+workerman实现相关推荐

  1. 最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码

    最新在线客服系统php代码微信软件公众号小程序app二维码聊天网站源码 管理界面 独家长期更新日志(欢迎反馈BUG) 1.添加手机端前后台声音提示 2.添加后台客户管理显示在线离线 3.添加清空当前对 ...

  2. 智能在线客服系统源码 国际版多语言多商户智能机器人源码

    一套智能在线客服系统源码 多商户网页客服系统源码 支持二十种国际语言 带机器人自动回复. 框架:Thinkphp5+workerman, 环境:nginx+php7.3+mysql5.6 支持H5+公 ...

  3. 宝塔实测-PHP网页版在线客服系统源码

    大家好啊,我是测评君,欢迎来到web测评. 本期给大家带来一套PHP网页版在线客服系统源码. 运行环境 服务器宝塔面板 PHP 7.2 Mysql 5.6 Linux Centos7以上 文字安装教程 ...

  4. ThinkPHP核心多商户版在线客服程序

    简介: ThinkPHP核心多商户版在线客服对接适用场景[PC+WAP+公众号] 源码分享 运行环境: 服务器系统:Linux + Centos7.x + 宝塔 亲测环境:Nginx 1.18.0 + ...

  5. 个人版独立在线客服系统搭建教程_私有化开发安全有保障

    做平台,做运营,少不了一个东西,在线客服!有人会说,在线客服不就处理点售前售后问题吗?有必要单独使用一个系统吗?如果你问出这个问题,可能你还是一个运营小白.相比直接用微信和QQ作为客服,独立在线客服没 ...

  6. 【教程】腾讯轻量云搭建在线客服聊天系统

    前言 这次我们继续来整活,搭建一个whisper在线客服系统 系统简介 whisper是一个在线客服系统源码,采用thinkphp5+Gatewayworker编写,性能强悍.自己搭建,控制在自己,也 ...

  7. PHP多商户AI智能在线客服系统源码 机器人自动回复 即时通讯聊天系统源码

    一套智能在线客服系统源码 多商户网页客服系统源码 支持二十种国际语言 带机器人自动回复. 框架:Thinkphp5+workerman, 环境:nginx+php7.3+mysql5.6 支持H5+公 ...

  8. ThinkPHP 在线客服系统

    基于ThinkPHP5+FastAdmin+Workerman开发的一款实时在线客服系统,支持多客服(不限座席).知识库.离线留言板.离线消息.历史会话.微信小程序接入.用户轨迹等功能,提供全部无加密 ...

  9. php welive,WeLive免费开源PHP在线客服系统下载

    WeLive(在线客服系统)是一款专业的免费开源PHP在线客服系统,此款系统功能十分强大,支持客户端浏览器与远程主机之间进行全双工通信,即允许服务器主动推送信息给客户端,具有节约带宽.实时性强等特点. ...

  10. 多商户无限座席在线客服在线对话聊天系统源码,防黑防丢,完美商用支持app公众号网页H5

    源码介绍 外面的现在这个内核的基本都是有一个gif图片木马后门的,这个请一定注意一定小心,别贪便宜吃了大亏!!!! 几天给大家放送一套非常不错的源码!锦尚中国自用的在线客服系统,诸多的客户搭建网站的同 ...

最新文章

  1. 1数字图像获取:1.3图像处理算法的形式
  2. 要懂得利用和筛选友情链接
  3. Shell之系统函数和自定义函数
  4. c语言不可见字符的ascii,转CHAR不可见字符
  5. 陕西师范大学计算机科学学院保研院校,陕西师范大学计算机科学学院(专业学位)现代教育技术保研细则...
  6. Eclipse使用Maven插件创建Web项目时出错:Could not resolve archetype org.apache.maven.archetypes
  7. java面试题_1000道Java工程师面试题+答案PDF485页
  8. Javascript特效:长图滚动
  9. 人工智能中蕴含的情商
  10. SCM供应链管理系统介绍:企业SCM供应链系统应用领域、优势、功能详解
  11. Python3.5学习之旅——day5
  12. linux平台生成awr报告,Linux平台生成awr报告
  13. sgu-244 Height, Bisector and Median
  14. 位地址和字节地址换算_IP地址详解
  15. Apex_json应用
  16. 为什么python代码运行不了_为什么我的python代码不能正常运行?
  17. 2022年云南最新建筑八大员(市政)模拟考试题库及答案
  18. 迅搜(xunsearch)的安装使用以及操作类分享
  19. 如何设置一台电脑双网卡双线上网
  20. python气象绘图速成_Python气象绘图教程(十六)—Cartopy_6

热门文章

  1. Thinkpad E40 Xp下安装AHCI驱动
  2. Ajax——判断用户名是否已经注册
  3. ios-deploy 安装与使用
  4. SAP系统 - ABAVN固定资产报废解析之完全报废案例
  5. 性能测试方案与性能测试报告目录导航
  6. 大写汉字转为阿拉伯数字
  7. 前端开发的 学php吗,web前端开发难学吗
  8. gitlab安装--数据备份迁移恢复
  9. jQuery实现无刷新切换主题皮肤功能
  10. js中创建桌面网页快捷方式代码