Correcting teacher:Guanhui
Correction status:qualified
Teacher's comments:标题可以适当的简洁些!
都是复习, DOM操作, js,jQuery操作等. 基本实现西门老师上课讲的功能内容.
cURL
的使用, 基础课没教, 在这里卡了蛮久, 需要找时间学习.
切换客户聊天记录容器: 使用类似朱老师教的”页签菜单切换”demo.
客服端刷新后, 找回正在沟通的客户: 客户端在创建链接前, 强制先输入手机号. 客服端通过后台管理系统, 用账号登录. 这样就可以用手机号或客服账号做客户连接对象全局数组/客服连接对象全局数组的key. 同时连接对象也设置属性identity
, 为其赋值客户手机号或客服账号.
sendId
值为客服账号的连接属性, 将其identity
(即手机号)发送消息给客服页面, 客服页面遍历手机号数组, 把这些客户重新添加回客户列表. 然后以客户手机号, 客服账号做查询条件, 使用cURL
模拟想laravel发送GET
请求, 通过laravel从数据库中查询聊天记录, 并渲染回各个客户的”聊天页签”中(回填聊天记录没做了, 懒…).提供websocket
通信的服务器(也就是warkerman
的应用服务器), 使用cURL
模拟发送POST
请求到laravel, 通过laravel的控制器方法操作数据库, 把聊天记录保存到数据库.
VerifyCsrfToken
中间件中, 把定位到保存聊天记录到数据库的控制器方法的路由加入到$except
属性数组中, 即, 告诉laravel, 这个路由的post请求就不用验证token了.1- 客服端界面
2- 客户端界面
3- 客服小姐姐分配到客户时的客服端界面
4- 客户端收发消息
5-客服端收发消息
warkerman
搭建websocket
通信服务器
<?php
use Workerman\Worker;
require_once __DIR__ . '/workerman/Autoloader.php';
// 加载发送请求的方法
require_once 'save_msg.php';
// 注意:这里与上个例子不同,使用的是websocket协议
$ws_worker = new Worker("websocket://0.0.0.0:2000");
// 启动4个进程对外提供服务
$ws_worker->count = 4;
/* 创建全局连接数组,key=连接的id,val=连接; 因为存在客户可能刷新浏览器页面, 触发websocket给同一个客户再分配一个新的连接id
* 所以, 一般是用客户保存在数据表中的用户id来做key, 每次刷新, 用户id都跟最新分配的连接关联, 就能解决用户刷新的问题了.
* 用户id从哪来? 可以在登录成功后把用户id保存到cookie中.
* 另一种方案: 把$conns链接数组保存到缓存(如: Redis)中, 同样用用户id做key, 序列化/json格式化的连接做value.
*/
/*
* 新版本: key改为客户在前端录入的手机号, 使用消息数组中key为from_id的元素存储;
* 客服数组的key改为管理员账号, 同样用from_id存储
*/
// 客户连接数组
$customerConns = [];
// 客服连接数组
$servicerConns = [];
// 发送约定格式的消息数组(转换成json)
function sendMessage($conn, $from_id, $type, $msg, $custom_id=null) {
$sendInfo['from_id'] = $from_id;
$sendInfo['type'] = $type;
$sendInfo['msg'] = $msg;
if($custom_id != null) {
$sendInfo['custom_id'] = $custom_id;
}
$conn->send(json_encode($sendInfo));
}
function saveMessage($from, $to, $msg) {
$msgInfo['from'] = $from;
$msgInfo['to'] = $to;
$msgInfo['msg'] = $msg;
$msgInfo['send_time'] = time();
saveMsg('cms.com/admin/servicer/savemsg', $msgInfo);
}
// 当收到客户端发来的数据后返回hello $data给客户端
$ws_worker->onMessage = function($connection, $data)
{
global $customerConns;
global $servicerConns;
// 分辨用户类型, 只能客户和客服之间通信.
// 判断客户端模拟用户登录状态的标识type, 若值为login标识登录成功. 则把用户的类型(客户/客服)
// 以自定义属性的方式设置到$connection(即连接)中
// json->数组
$data = json_decode($data, true);
if($data['type'] == 'login') {
var_dump($connection->id);
// 给连接动态加入group属性,标识[客户]和[客服]
$connection->group = $data['group'];
// 改用客户前端录入的手机号/客服小姐姐的登录账号作为连接的识别码, 不用$connection->id了
$connection->identity = $data['from_id'];
// 模拟"登录"的连接,放入到对应连接数组中
if($data['group'] == 'admin') {// admin标识为[客服]
var_dump('客服小姐姐' . $data['from_id'] . '上线了, 其分配到的链接id为: ' . $connection->id);
// 改用客服小姐姐的登录账号作为key
// $servicerConns[$connection->id] = $connection;
$servicerConns[$data['from_id']] = $connection;
// 遍历客户连接全局数组, 找到sendId为当前客服小姐姐的客户链接, 返回给这个客服小姐姐
$customPhoneNumbers = [];
foreach($customerConns as $phoneNumber => $customerConn) {
if(!empty($customerConn->sendId) && $customerConn->sendId == $connection->identity) {
$customPhoneNumbers[] = $phoneNumber;
}
}
// 找到这位客服小姐姐服务的客户
if(count($customPhoneNumbers) > 0) {
sendMessage($connection, 'system', 'login', '继续为[' . implode(',', $customPhoneNumbers) . ']服务吧', $customPhoneNumbers);
}
} else {// member标识为[客户]
// DEL: 改用用户在前端录入的手机号作为key
// $customerConns[$connection->id] = $connection;
$customerConns[$data['from_id']] = $connection;
// 如果是客户登录, 还需要给他安排一个客服(array_rand()函数随机返回数组元素的key值)
$connection->sendId = array_rand($servicerConns, 1);
// 没有小姐姐可供分配
// if(!is_numeric($connection->sendId)) {
if(empty($connection->sendId)) {
sendMessage($connection, 'system', 'msg', '暂无客服小姐姐在线, 请稍后刷新重试');
var_dump('暂无客服小姐姐');
return;
}
var_dump('给手机号为'.$connection->identity.'的客户(链接id: '.$connection->id.')分配的是'.$connection->sendId.'客服小姐姐(链接id: '.$servicerConns[$connection->sendId]->id.')');
// 通知这位客服, 有新客户进来
$target = $servicerConns[$connection->sendId];
sendMessage($target, 'system', 'login', '有新客户登录, 电话号码为: ' . $connection->identity, $connection->identity);
}
} else if($data['type'] == 'msg') {// 模拟"发送数据"的连接
// 判断发送数据的连接是[客服]还是[客户]
if($connection->group == 'member') {// 客户
// if(!is_numeric($connection->sendId)) {
if(empty($connection->sendId)) {
sendMessage($connection, 'system', 'msg', '为您服务的小姐姐可能已掉线, 请刷新');
var_dump('暂无客服小姐姐');
return;
}
// 获取在客户登录时指定的客服连接
$target = $servicerConns[$connection->sendId];
var_dump('客户' .$connection->identity . '给账号为' . $connection->sendId . '的客服小姐姐发信息');
sendMessage($target, $connection->identity, 'msg', $data['msg']);
// 保存消息到数据库
saveMessage($connection->identity, $target->identity, $data['msg']);
} else if($connection->group == 'admin') {// 客服
// 跟谁说话
$phoneNumber = $data['sendId'];
if(empty($phoneNumber) || !isset($customerConns[$phoneNumber])) {
sendMessage($connection, 'system', 'msg', '该用户不存在, 可能已下线');
return;
}
// 要跟其说话的客户的链接对象
$target = $customerConns[$phoneNumber];
sendMessage($target, $connection->identity, 'msg', $data['msg']);
saveMessage($connection->identity, $target->identity, $data['msg']);
var_dump('客服' .$connection->identity . '给手机号为' . $phoneNumber . '的客户发信息');
}
}
};
// 当有连接断开时
$ws_worker->onClose = function($connection) {
global $servicerConns;
global $customerConns;
if($connection->group == 'admin') {// 客服断开
$unconnId = $connection->identity;//$connection->id;
// 把断开的客服连接移除出客服连接数组
unset($servicerConns[$connection->id]);
var_dump('客服' . $unconnId . '下线了');
// 客服断开, 需要给该客服负责的客户重新分配新客服
foreach($customerConns as $customerConn) {
if($customerConn->sendId == $unconnId) {// 该客服小姐姐负责的客户
$customerConn->sendId = array_rand($servicerConns, 1);
// 没分配到客服小姐姐, 直接结束分配.
if(empty($customerConn->sendId)) {
sendMessage($connection, 'system', 'msg', '坏了, 客服小姐姐的网络开小差了, 请稍后刷新重试吧');
var_dump('当前没有客服小姐姐在线');
continue;
}
var_dump('重新给手机号为'.$customerConn->identity.'的客户(链接id: '.$customerConn->id.')分配的是'.$customerConn->sendId.'客服小姐姐(链接id: '.$servicerConns[$customerConn->sendId]->id.')');
// 新分配的客服小姐姐的连接
$target = $servicerConns[$customerConn->sendId];
// 给新分配到的客服小姐姐发分配消息
sendMessage($target, 'system', 'login', '有新客户登录, id为:' . $customerConn->identity, $customerConn->identity);
}
}
} else {// 客户断开
// 断开的客户连接id
$unconnId = $connection->identity;
var_dump('客户' . $unconnId . '下线了');
// 负责该客户的客服小姐姐id
$servicerId = $connection->sendId;
// 把断开的客户连接移除出客户连接数组
unset($customerConns[$connection->identity]);
if(empty($servicerId)) {// 判断断开的客户是否有客服接待, 没有, 则直接断开客户连接;
return;
}
// 客户断开, 系统给负责该客户的客服发消息, 不必再负责该客户
$target = $servicerConns[$servicerId];
sendMessage($target, 'system', 'logout', '客户' . $unconnId . '跟你说了声拜拜后, 下线了', $unconnId);
}
};
// 运行worker
Worker::runAll();
cURL
模拟发送保存聊天记录的脚本
<?php
function saveMsg($url, $data) {
// $header = ["Content-Type:application/x-www-form-urlencoded", "token:test", "client:h5"];
$header = ["Content-Type:application/json", "token:test", "client:h5"];
$res = curlPost($url, $data, 5, $header, 'json');
var_dump($res);
return $res;
}
/**
* 传入数组进行HTTP POST请求
*/
function curlPost($url, $post_data = array(), $timeout = 5, $header = "", $data_type = "") {
$header = empty($header) ? '' : $header;
//支持json数据数据提交
if($data_type == 'json'){
$post_string = json_encode($post_data);
}elseif($data_type == 'array') {
$post_string = $post_data;
}elseif(is_array($post_data)){
$post_string = http_build_query($post_data, '', '&');
}
var_dump($post_string);
$ch = curl_init(); // 启动一个CURL会话
curl_setopt($ch, CURLOPT_URL, $url); // 要访问的地址
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查 // https请求 不验证证书和hosts
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
// curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
curl_setopt($ch, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的Post请求
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string); // Post提交的数据包
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
//curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 获取的信息以文件流的形式返回
curl_setopt($ch, CURLOPT_HTTPHEADER, $header); //模拟的header头
$result = curl_exec($ch);
// 打印请求的header信息
//$a = curl_getinfo($ch);
//var_dump($a);
curl_close($ch);
return $result;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>"百度商桥"客服端</title>
<link rel="stylesheet" href="/static/plugin/layui/css/layui.css" media="all">
<script src="/static/plugin/layui/layui.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
padding: 10px;
width: 100vw;
height: 100vh;
background-color: #f0f0f0;
display: grid;
gap: 10px;
grid-template-columns: 240px auto;
grid-template-rows: 3fr 2fr;
grid-template-areas:
"customer-list message-list"
"customer-list message-send";
}
.customer-list {
grid-area: customer-list;
background-color: white;
border: 1px solid #ccc;
}
.message-list {
grid-area: message-list;
background-color: white;
overflow-y: auto;
padding: 10px;
display: grid;
grid-template-rows: 50px auto;
}
.message-list > .system-message {
height: 40px;
width: 100%;
background-color: wheat;
border: 1px solid #eaeaea;
margin-bottom: 10px;
border-radius: 5PX;
overflow-y: hidden;
}
.message-list > .private-chat-box {
background-color: #DFECEC;
border-radius: 5px;
}
.show {
display: block;
}
.hide {
display: none;
}
.message-send {
display: grid;
grid-auto-rows: auto 40px;
grid-area: message-send;
background-color: white;
padding: 10px;
}
.message-send > .message-input-area {
padding: 5px;
background-color: #fafafa;
border: 1px solid #ccc;
margin-bottom: 10px;
border-radius: 5px;
outline: none;
overflow-y: auto;
}
.message-send > .message-input-area:hover {
box-shadow: 0px 0px 1px #333;
}
.message-send > .btn-area {
width: 100%;
text-align: right;
}
.msg-box-friend {
padding: 10px;
width: 75%;
margin: 5px auto 0 5px;
background-color: lightblue;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
.msg-box-me {
padding: 10px;
width: 75%;
margin: 5px 5px 0 auto;
background-color: wheat;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
.customer-item {
border: 1px solid #e0e0e0;
border-radius: 5px;
margin: 5px;
padding: 5px 10px;
}
.active {
background-color: skyblue;
}
.bling {
color: red;
background-color: linen;
}
</style>
</head>
<body>
<input type="hidden" name="username" value="{{$username}}">
<!-- 客户列表 -->
<div class="customer-list">
</div>
<!-- 消息记录 -->
<div class="message-list">
<div class="system-message"></div>
<!-- <div class="private-chat-box"></div> -->
</div>
<!-- 发送消息 -->
<div class="message-send">
<div class="message-input-area" contenteditable="true">
</div>
<div class="btn-area">
<span class="layui-btn layui-btn-success" onclick="send()">发送</span>
</div>
</div>
</body>
<script>
layui.use(['layer'], function() {
layer = layui.layer;
$ = layui.jquery;
});
// 假设服务端ip为127.0.0.1
ws = new WebSocket("ws://127.0.0.1:2000");
/* 当客户端连通服务器端的时候 */
ws.onopen = function() {
// 当客户端连通服务端时, 把当前客户端的用户标识(客户/客服)发给服务端
var data = {};
// js对象的属性可以自定义. type: login, 标识用户行为为声明登录;type: msg, 标识用户行为为发送消息。
data.type = 'login';
// 约定admin代表登录的用户是客服
data.group = 'admin';
// 使用登录账号作为客服小姐姐的登录标识(因为链接id在刷新或关闭浏览器后值会改变)
data.from_id = $('input[name="username"]').val();
// 发送JSON格式的数据
ws.send(JSON.stringify(data));
};
ws.onmessage = function(e) {
var data = JSON.parse(e.data);
// alert("收到服务端的消息:" + e.data);
// 系统发来的消息, 表示有新客户接入, 并分配到当前客服小姐姐
if(data.from_id == 'system' && data.type == 'login') {
if(!Array.isArray(data.custom_id)) {
addOldCustomer(data.custom_id);
} else {
data.custom_id.forEach(function(item) {
addOldCustomer(item);
});
}
// 发送客户接入的系统消息
var str = "<span style='margin-right: 20px; color: red;'>系统消息: "+data.msg+"</span>";
$('.system-message').prepend($(str));
} else if(data.from_id == 'system' && data.type == 'logout') {// 客户下线
// 客户列表移除客户
$('.customer-item[data-id="'+data.custom_id+'"]').remove();
// 聊天记录窗口移除聊天容器
$('.private-chat-box[data-id="'+data.custom_id+'"]').remove();
// 系统消息走一波
// 发送客户接入的系统消息
var str = "<span style='margin-right: 20px;'>系统消息: 客户"+data.custom_id+"下线了</span>";
$('.system-message').prepend($(str));
} else if(data.type = 'msg') {// 客户给客服发消息
// 客户列表中的客户项背景色变一下再还原
// 客户列表中的当前客户项
var customerItem = $('.customer-item[data-id="'+data.from_id+'"]');
blingbling(customerItem);
// 获取正在聊天的窗口的data-id值
var chatting_id = $('.private-chat-box').filter('.show').data('id');
// 当前没有正在聊天的窗口, 则显示跟发送消息的客户的聊天窗口
if(chatting_id == undefined) {
// 显示聊天对话框
var chatbox = $('.private-chat-box').filter('[data-id="'+data.from_id+'"]');
// chatbox.removeClass('hide').addClass('show');
// 相当于点击当前发送消息的客户的客户向
var customItem = $('.customer-item[data-id="'+data.from_id+'"]')
talkTo(customerItem[0]);
// 显示客户讲的消息
var str = "<div class='msg-box-friend'>"+data.from_id+"说: "+data.msg+"</div>";
$(str).appendTo(chatbox);
} else if(chatting_id != data.from_id) {// 正在聊天的客户不是当前发送消息的客户
// 把消息插入跟当前客户的聊天窗口
var str = "<div class='msg-box-friend'>"+data.from_id+"说: "+data.msg+"</div>";
$(str).appendTo($('.private-chat-box').filter('[data-id="'+data.from_id+'"]'));
// 在客户列表中当前发送消息的客户项右边加上未读标签数量
// 客户项中的未读消息数量框
var msgCount = customerItem.find('.layui-badge');
// 如果没有, 表示之前没有未读消息, 加上即可
if(msgCount == undefined || msgCount.length < 1) {
$('<span class="layui-badge">1</span>').appendTo(customerItem);
} else {// 有, 未读消息加一
var count = parseInt(msgCount.html()) + 1;
msgCount.html(count);
}
} else if(chatting_id == data.from_id) {// 当前聊天窗口就是当前发送消息的客户
// 逻辑可以直接用chatting_id是undefined的逻辑, 后期考虑合并
// 显示聊天对话框
var chatbox = $('.private-chat-box').filter('[data-id="'+data.from_id+'"]');
chatbox.removeClass('hide').addClass('show');
console.log(chatbox);
// 显示客户讲的消息
var str = "<div class='msg-box-friend'>"+data.from_id+"说: "+data.msg+"</div>";
$(str).appendTo(chatbox);
}
}
};
// 客服刷新网页, 找回正在沟通的客户列表
function addOldCustomer(custom_id) {
// 把新登录的客户加到客户列表区
var customer = $('<div class="customer-item" data-id="'+custom_id+'" onclick="talkTo(this)">客户'+custom_id+'</div>');
customer.appendTo('.customer-list');
// 闪一下
blingbling(customer);
// 在消息记录容器(message-list)中插入跟登录的客户聊天的对话框div
var privateChatBox = '<div class="private-chat-box hide" data-id="'+custom_id+'"></div>';
$(privateChatBox).appendTo('.message-list');
}
// 客户上线/有未读消息/有新消息, 变一下色, 2秒后复原
function blingbling(jqele) {
jqele.addClass('bling');
setTimeout(() => {
jqele.removeClass('bling');
}, 2000);
}
// 点击客户列表区, 选择要聊天的客户对象
function talkTo(ele) {
$(ele).siblings().removeClass('active');
$(ele).addClass('active');
// 显示聊天窗口
var dataId = $(ele).data('id');
$('.private-chat-box').removeClass('show').addClass('hide');
$('.private-chat-box[data-id="'+dataId+'"]').removeClass('hide').addClass('show');
// 移除未读消息
$(ele).find('.layui-badge').remove();
}
function send() {
var str = "<div class='msg-box-me'>我说: "+$('.message-input-area').html()+"</div>";
var data = {};
// 标识此次发送的数据是发送消息
data.type='msg';
// 标识是从客服端发的
data.group = 'admin'
// 获取当前选中的客户
var customer_id = $('div[class*=active]').data('id');
if(isNaN(customer_id)) {
return layer.alert('请先选中一个客户, 再发送消息.');
}
data.sendId = customer_id;
// 要发送的消息
data.msg = $('.message-input-area').html();
$(str).appendTo('.message-list > .private-chat-box.show');
// 转成json字符串发送。
ws.send(JSON.stringify(data));
$('.message-input-area').html('');
}
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>"百度商桥"客户端</title>
<link rel="stylesheet" href="/static/plugin/layui/css/layui.css" media="all">
<script src="/static/plugin/layui/layui.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #fafafa;
}
.im {
width: 400px;
height: 520px;
background-color: wheat;
margin: 40px auto;
padding: 10px;
box-shadow: 0 0 5px #999;
}
.im .history {
background-color: white;
border: 1px solid #aaa;
width: 100%;
height: 290px;
padding: 5px;
overflow-y: auto;
border-radius: 5px;
}
.im .inputing {
background-color: white;
border: 1px solid #aaa;
width: 100%;
height: 150px;
margin-top: 10px;
padding: 5px;
outline: none;
border-radius: 5px;
}
.im .btn-area {
width: 100%;
text-align: right;
margin-top: 10px;
}
.msg-box-friend {
padding: 10px;
width: 75%;
margin: 5px auto 0 5px;
background-color: lightblue;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
.msg-box-me {
padding: 10px;
width: 75%;
margin: 5px 5px 0 auto;
background-color: wheat;
border: 1px solid #ccc;
border-radius: 5px;
/* overflow-x: wordwrap; */
white-space:normal;
}
</style>
</head>
<body>
<input type="hidden" name="phone_number" value="">
<div class="im">
<div class="history">
</div>
<!-- contenteditable="true", 这个div就可编辑了 -->
<div class="inputing" contenteditable="true">
</div>
<div class="btn-area">
<span class="layui-btn layui-btn-success" onclick="send()">发送</span>
</div>
</div>
</body>
<script>
layui.use(['layer'], function() {
layer = layui.layer;
$ = layui.jquery;
// 在layer加载完成后再弹出, 否则无法上下左右居中显示弹出框.
layer.ready(function() {
// 用户填入手机号
getPhoneNumber();
});
});
function getPhoneNumber() {
layer.prompt({
formType: 0,
title: '请输入你的手机号',
area: ['800px', '350px'],
btn: ['确定']
}, function(value, index, elem) {
// 验证是否是有效地手机号码
if(!(/^1[3456789]\d{9}$/.test(value))){
return layer.alert("手机号码有误,请重填");
}
// 保存电话号码到隐藏域
$("input[name='phone_number']").val(value);
// 连接websocket服务器
connect(value);
layer.close(index);
});
}
function connect(value) {
// 假设服务端ip为127.0.0.1
ws = new WebSocket("ws://127.0.0.1:2000");
/* 当客户端连通服务器端的时候 */
ws.onopen = function() {
// 当客户端连通服务端时, 把当前客户端的用户标识(客户/客服)发给服务端
var data = {};
// js对象的属性可以自定义. type: login, 标识用户行为为声明登录;type: msg, 标识用户行为为发送消息。
data.type = 'login';
// 约定admin表示登录的用户是客户
data.group = 'member';
// 识别客户的唯一码从连接id改为用户手机号, 因为刷新后, 连接id就会变.
data.from_id = value;
// 发送JSON格式的数据
ws.send(JSON.stringify(data));
};
// 从服务器端获取到消息时
ws.onmessage = function(e) {
// alert("收到服务端的消息:" + e.data);
var receive = JSON.parse(e.data);
var str = "<div class='msg-box-friend'>"+receive.from_id+"说: "+receive.msg+"</div>";
$(str).appendTo('.history');
};
}
function send() {
// 消息框
var str = "<div class='msg-box-me'>我说: "+$('.inputing').html()+"</div>";
var data = {};
// 标识此次发送的数据是发送消息
data.type='msg';
// 标识是从客服端发的
data.group = 'admin'
// 标识私聊的对象id,0标识群发. DEL_客户连接时由系统随机分配客服小姐姐, 不需要手动指定了
// data.sendId = 0;
// 要发送的消息
data.msg = $('.inputing').html();
// 在消息历史中显示发送的消息
$(str).appendTo('.history');
// 发送JSON格式的数据
ws.send(JSON.stringify(data));
$('.inputing').html('');
}
</script>
</html>
public function saveMsg(Request $req) {
$msg = $req->all();
DB::table('msg_list')->insert($msg);
return json_encode(['status' => 0, 'message' => '保存成功']);
}