博客列表 >workerman客服聊天系统

workerman客服聊天系统

大A
大A原创
2020年06月27日 22:54:472415浏览

介绍

随机分配客服,一个客服可同时与多人聊天.

源码

workerman.php

  1. <?php
  2. use Workerman\worker;
  3. require_once __DIR__ . '/Autoloader.php';
  4. $ws_worker = new Worker("websocket://0.0.0.0:2000");
  5. $ws_worker->count = 4;
  6. $ws_worker->onMessage = function ($connection, $data) {
  7. global $ws_worker;
  8. $adminlist = [];
  9. $msg = json_decode($data);
  10. switch ($msg->type) {
  11. case 'login':
  12. if ($msg->group === 'user') {
  13. $connection->group = 'user';
  14. foreach ($ws_worker->connections as $value) {
  15. if ($value->group === 'admin')
  16. $adminlist[] = $value->id;
  17. }
  18. if (!$adminlist) {
  19. $edata = new stdClass();
  20. $edata->fid = $connection->id;
  21. $edata->msg = '没有客服在线';
  22. $edata->name = '系统提示';
  23. $connection->send(json_encode($edata));
  24. return;
  25. }
  26. $connection->toid = $ws_worker->connections[$adminlist[array_rand($adminlist, 1)]];
  27. }
  28. if ($msg->group === 'admin_user') {
  29. $connection->group = 'admin';
  30. }
  31. break;
  32. case 'msg':
  33. if ($msg->group === 'user') {
  34. $fdata = new stdClass();
  35. $fdata->fid = $connection->id;
  36. $fdata->msg = $msg->msg;
  37. $fdata->name = '客户' . $connection->id;
  38. if (in_array ($connection->toid->id ,(array_column ((array) $ws_worker->connections,'id')))){
  39. $connection->toid->send(json_encode($fdata));
  40. }else{
  41. $edata = new stdClass();
  42. $edata->fid = $connection->id;
  43. $edata->msg = '已与客服断开连接,请刷新后重试';
  44. $edata->name = '系统提示';
  45. $connection->send(json_encode($edata));
  46. return;
  47. }
  48. }
  49. if ($msg->group === 'admin_user') {
  50. if ($msg->toid != null) {
  51. $fdata = new stdClass();
  52. $fdata->fid = $connection->id;
  53. $fdata->msg = $msg->msg;
  54. $fdata->name = '客服' . $connection->id;
  55. $ws_worker->connections[$msg->toid]->send(json_encode($fdata));
  56. }
  57. }
  58. break;
  59. default:
  60. # code...
  61. break;
  62. }
  63. // $connection->send('hello ' . $data);
  64. };
  65. // 运行worker
  66. Worker::runAll();

kehu.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <style>
  7. .item {
  8. margin: 10px;
  9. margin-bottom: 10px;
  10. padding-left: 5px;
  11. padding-right: 5px;
  12. }
  13. </style>
  14. <title>Document</title>
  15. </head>
  16. <body>
  17. <div id="msg" style="width:100%;border: 1px solid;overflow-y:scroll;">
  18. </div>
  19. <div id="content" contenteditable="true" style="width:100%;margin-top: 2px;border: 1px solid;overflow-y:scroll;"></div>
  20. </body>
  21. <script>
  22. window.onload = function() {
  23. document.getElementById('msg').style.height = '65vh';
  24. document.getElementById('content').style.height = '30vh';
  25. }
  26. function send() {
  27. var text = document.getElementById('content').innerText;
  28. data=new Object();
  29. data.group='user';
  30. data.type='msg';
  31. data.msg=text;
  32. ws.send(JSON.stringify(data));
  33. document.getElementById('content').innerText = '';
  34. add_msg(text);
  35. var scrollTarget = document.getElementById("msg");
  36. scrollTarget.scrollTop = scrollTarget.scrollHeight;
  37. }
  38. ws = new WebSocket("ws://php.edu:2000");
  39. ws.onopen = function() {
  40. console.log("连接成功");
  41. data=new Object();
  42. data.group='user';
  43. data.type='login';
  44. ws.send(JSON.stringify(data));
  45. };
  46. ws.onmessage = function(e) {
  47. fdata = JSON.parse(e.data);
  48. add_msg(fdata.msg, fdata.name);
  49. var scrollTarget = document.getElementById("msg");
  50. scrollTarget.scrollTop = scrollTarget.scrollHeight;
  51. };
  52. function add_msg(text, id) {
  53. var item = document.createElement('item');
  54. if (id == null) {
  55. id = '我说';
  56. style = 'style="display:flex;flex-direction: column;align-items: flex-end;"'
  57. } else {
  58. style = '';
  59. }
  60. r = '<div class="item" ' + style + '><div>' + id + '<span style="color: #f55;">' + ' ' + new Date().toLocaleTimeString('cn', {
  61. hour12: false
  62. }) + '</span></div> <div style="padding-left: 10px;">' + text + '</div></div>'
  63. item.innerHTML = r;
  64. document.getElementById('msg').append(item);
  65. }
  66. </script>
  67. </html>

kefu.php

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <style>
  7. .item {
  8. margin: 10px;
  9. margin-bottom: 10px;
  10. padding-left: 5px;
  11. padding-right: 5px;
  12. }
  13. .navid {
  14. position: absolute;
  15. height: 70.3vh;
  16. width: 10vw;
  17. border: 1px solid;
  18. overflow-y: scroll;
  19. left: 8.7vw;
  20. }
  21. .up {
  22. position: absolute;
  23. height: 50vh;
  24. width: 80vw;
  25. border: 1px solid;
  26. overflow-y: scroll;
  27. right: 1vw;
  28. }
  29. .hide {
  30. display: none;
  31. }
  32. .down {
  33. position: absolute;
  34. top: 51vh;
  35. width: 80vw;
  36. height: 20vh;
  37. margin-top: 2px;
  38. border: 1px solid;
  39. overflow-y: scroll;
  40. right: 1vw;
  41. }
  42. .btn {
  43. position: absolute;
  44. top: 72vh;
  45. right: 1vw;
  46. width: 100px;
  47. height: 30px;
  48. margin-top: 0.3vh;
  49. }
  50. .kehuitem {
  51. width: 98%;
  52. height: 5vh;
  53. border-bottom: 1px solid;
  54. line-height: 5vh;
  55. text-align: center;
  56. }
  57. .kehuitem:hover {
  58. background-color: cornflowerblue;
  59. cursor: default;
  60. }
  61. </style>
  62. <title>Document</title>
  63. </head>
  64. <body>
  65. <div class="navid" id="idlist">
  66. {{-- <div class="kehuitem">客户5686</div> --}}
  67. </div>
  68. <div class="up" id="msg">
  69. </div>
  70. <div class="down" id="content" contenteditable="true"></div>
  71. <input class="btn" type="button" value="发送" onclick="send()">
  72. </body>
  73. <script>
  74. var toid;
  75. function send() {
  76. var text = document.getElementById('content').innerText;
  77. data = new Object();
  78. data.group = 'admin_user';
  79. data.type = 'msg';
  80. data.msg = text;
  81. all_list = document.getElementsByClassName('up');
  82. for (const key in all_list) {
  83. if (all_list.hasOwnProperty(key)) {
  84. const element = all_list[key];
  85. if (element.style.display == 'block') {
  86. toid = element.getAttribute('toid');
  87. console.log(data.toid);
  88. break;
  89. }
  90. }
  91. }
  92. if (toid == undefined) {
  93. data.toid = null;
  94. } else {
  95. data.toid = toid;
  96. }
  97. ws.send(JSON.stringify(data));
  98. document.getElementById('content').innerText = '';
  99. add_msg(text);
  100. var scrollTarget = document.getElementById("msg");
  101. scrollTarget.scrollTop = scrollTarget.scrollHeight;
  102. }
  103. function add_msg(text, id) {
  104. var item = document.createElement('div');
  105. if (id == null) {
  106. id = '我说';
  107. style = 'style="display:flex;flex-direction: column;align-items: flex-end;"'
  108. } else {
  109. style = '';
  110. }
  111. r = '<div class="item" ' + style + '><div>' + id + '<span style="color: #f55;">' + ' ' + new Date()
  112. .toLocaleTimeString('cn', {
  113. hour12: false
  114. }) + '</span></div> <div style="padding-left: 10px;">' + text + '</div></div>'
  115. item.innerHTML = r;
  116. document.getElementById('msg').append(item);
  117. }
  118. ws = new WebSocket("ws://php.edu:2000");
  119. ws.onopen = function () {
  120. console.log("连接成功");
  121. data = new Object();
  122. data.group = 'admin_user';
  123. data.type = 'login';
  124. ws.send(JSON.stringify(data));
  125. };
  126. ws.onmessage = function (e) {
  127. fdata = JSON.parse(e.data);
  128. show_msg(fdata.name, fdata.fid, fdata.msg);
  129. add_msg(fdata.msg, fdata.name);
  130. var scrollTarget = document.getElementById("msg");
  131. scrollTarget.scrollTop = scrollTarget.scrollHeight;
  132. };
  133. //收到消息后处理
  134. function show_msg(s_title, s_id, s_msg) {
  135. exist = false;
  136. all_list = document.getElementsByClassName('kehuitem');
  137. for (const key in all_list) {
  138. if (all_list.hasOwnProperty(key)) {
  139. const element = all_list[key];
  140. if (element.getAttribute('toid') == s_id) {
  141. exist = true;
  142. break;
  143. }
  144. }
  145. }
  146. if (exist) {
  147. all_chat_box = document.getElementsByClassName('up');
  148. for (const key in all_chat_box) {
  149. if (all_chat_box.hasOwnProperty(key)) {
  150. const element = all_chat_box[key];
  151. element.setAttribute('id', 'null');
  152. if (element.getAttribute('toid') == s_id) {
  153. element.setAttribute('id', 'msg');
  154. }
  155. }
  156. }
  157. all_list = document.getElementsByClassName('kehuitem');
  158. for (const key in all_list) {
  159. if (all_list.hasOwnProperty(key)) {
  160. const element = all_list[key];
  161. if (element.getAttribute('toid') == s_id) {
  162. element.style.backgroundColor = 'cornflowerblue';
  163. element.setAttribute('new', 'on');
  164. }
  165. }
  166. }
  167. } else {
  168. add_user(s_title, s_id, s_msg);
  169. all_list = document.getElementsByClassName('kehuitem');
  170. for (const key in all_list) {
  171. if (all_list.hasOwnProperty(key)) {
  172. const element = all_list[key];
  173. if (element.getAttribute('toid') == s_id) {
  174. element.style.backgroundColor = 'cornflowerblue';
  175. }
  176. }
  177. }
  178. }
  179. }
  180. //添加聊天标签
  181. function add_user(title, to_id, msg) {
  182. //在消息列表添加一个用户框
  183. userlist = document.createElement('div');
  184. userlist.setAttribute('class', 'kehuitem');
  185. userlist.setAttribute('toid', to_id);
  186. userlist.setAttribute('new', 'on');
  187. userlist.innerText = title;
  188. document.getElementById('idlist').append(userlist);
  189. //添加一个聊天框
  190. all_chat_box = document.getElementsByClassName('up');
  191. for (const key in all_chat_box) {
  192. if (all_chat_box.hasOwnProperty(key)) {
  193. const element = all_chat_box[key];
  194. element.setAttribute('id', 'null');
  195. element.style.display = 'none';
  196. }
  197. }
  198. chat_box = document.createElement('div');
  199. chat_box.setAttribute('class', 'up');
  200. chat_box.setAttribute('toid', to_id);
  201. chat_box.setAttribute('id', 'msg');
  202. chat_box.style.display = 'block';
  203. document.getElementsByTagName('body')[0].append(chat_box);
  204. //用户列表被点击
  205. userlist.addEventListener('click', function () {
  206. all_list = document.getElementsByClassName('kehuitem');
  207. for (const key in all_list) {
  208. if (all_list.hasOwnProperty(key)) {
  209. const element = all_list[key];
  210. if (element.getAttribute('new')=='off'){
  211. element.style.backgroundColor = '';
  212. }
  213. }
  214. }
  215. this.style.backgroundColor = 'cornflowerblue';
  216. this.setAttribute('new','off');
  217. to_id = this.getAttribute('toid');
  218. console.log(to_id);
  219. all_chat_box = document.getElementsByClassName('up');
  220. for (const key in all_chat_box) {
  221. if (all_chat_box.hasOwnProperty(key)) {
  222. const element = all_chat_box[key];
  223. element.setAttribute('id', 'null');
  224. if (element.getAttribute('toid') == to_id) {
  225. element.style.display = 'block';
  226. element.setAttribute('id', 'msg');
  227. } else {
  228. element.style.display = 'none';
  229. }
  230. }
  231. }
  232. });
  233. }
  234. </script>
  235. </html>

演示效果

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
2020-09-22 11:26:311楼
大佬,能给个源码吗?想学习一下