Blogger Information
Blog 17
fans 1
comment 0
visits 20049
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
workerman客服聊天系统
大A
Original
2416 people have browsed it

介绍

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

源码

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>

演示效果

Correcting teacher:天蓬老师天蓬老师

Correction status:qualified

Teacher's comments:棒
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
1 comments
2020-09-22 11:26:31
大佬,能给个源码吗?想学习一下
1 floor
Author's latest blog post
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!