多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
这里用得不是workerman框架而是gatewayworker手册。 因为做的是客户端与客户端之间的通讯。 php方面使用的是thinkphp框架。 现在开始重新讲一下怎么搞这个单对单聊天系统。 首先下载好thinkphp5与gatewayworker之后把gate(简读)放到thinkphp5的vendor文件夹下, ![](https://img.kancloud.cn/84/27/8427181565784f01e2d9f3ec5a718c03_179x360.png) 然后对gate框架的start_gateway.php文件进行配置 ![](https://img.kancloud.cn/ca/ed/caed025763ba3d16c963133e186ab3f9_693x652.png) 业务逻辑代码主要放在Events.php文件里。 这是gate的目录结构: ![](https://img.kancloud.cn/31/3f/313fc8fecd064dab20fff07576a717ac_836x412.png) 然后就是前端代码了,我这里是用别人教程的一个模板,根据里面的代码做一下简单的修改,适合入门。 这里是html的代码 ````<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="format-detection" content="telephone=no" /> <title>沟通中</title> <link rel="stylesheet" type="text/css" href="__STATIC__/newcj/css/themes.css?v=2017129"> <link rel="stylesheet" type="text/css" href="__STATIC__/newcj/css/h5app.css"> <link rel="stylesheet" type="text/css" href="__STATIC__/newcj/fonts/iconfont.css?v=2016070717"> <script src="https://code.jquery.com/jquery-3.0.0.min.js"></script> <script src="__STATIC__/newcj/js/dist/flexible/flexible_css.debug.js"></script> <script src="__STATIC__/newcj/js/dist/flexible/flexible.debug.js"></script> </head> <body ontouchstart> <div class='fui-page-group'> <div class='fui-page chatDetail-page'> <div class="chat-header flex"> <i class="icon icon-toleft t-48"></i> <span class="shop-titlte t-30">商店</span> <span class="shop-online t-26"></span> <span class="into-shop">进店</span> </div> <div class="fui-content navbar" style="padding:1.2rem 0 1.35rem 0;"> <div class="chat-content"> <p style="display: none;text-align: center;padding-top: 0.5rem" id="more"><a>加载更多</a></p> <p class="chat-time"><span class="time">2017-11-12</span></p> </div> </div> <div class="fix-send flex footer-bar"> <i class="icon icon-emoji1 t-50"></i> <input class="send-input t-28" maxlength="200"> <i class="icon icon-add t-50" style="color: #888;"></i> <span class="send-btn">发送</span> </div> </div> </div> <script> var fromid = 12; // var toid = 13; var API_URL = "http://localhost/tchat/public/index.php/api/api/"; var ws = new WebSocket("ws://192.168.0.102:8282"); // var ws = new WebSocket("ws://192.168.10.51:8282"); ws.onmessage = function(e){ var message = eval("("+e.data+")"); switch (message.type){ case "init": var bild = '{"type":"bind","fromid":"'+fromid+'"}'; ws.send(bild); return; case "text": console.log(message); if(toid==message.fromid) { $(".chat-content").append(' <div class="chat-text section-left flex"><span class="char-img" style="background-image:"></span> <span class="text"><i class="icon icon-sanjiao4 t-32"></i>' + message.data + '</span> </div>'); } return; case "save": save_message(message); return; } // $(".chat-content").append(' <div class="chat-text section-left flex"><span class="char-img" style="background-image: "></span> <span class="text"><i class="icon icon-sanjiao4 t-32"></i>' + message.data + '</span> </div>'); // console.log(message); } $(".send-btn").click(function(){ var text = $(".send-input").val(); var message = '{"data":"'+text+'","type":"say","fromid":"'+fromid+'","toid":"'+toid+'"}'; $(".chat-content").append('<div class="chat-text section-right flex"><span class="text"><i class="icon icon-sanjiao3 t-32"></i>'+text+'</span> <span class="char-img" style="background-image: "></span> </div>'); ws.send(message); $(".send-input").val(""); }) function save_message(message){ $.post( API_URL+"insertchat" , message, function(){ },'json' ) } </script> </body> </html> ```` 下面是php逻辑代码: ~~~ <?php /** * This file is part of workerman. * * Licensed under The MIT License * For full copyright and license information, please see the MIT-LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @author walkor<walkor@workerman.net> * @copyright walkor<walkor@workerman.net> * @link http://www.workerman.net/ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ /** * 用于检测业务代码死循环或者长时间阻塞等问题 * 如果发现业务卡死,可以将下面declare打开(去掉//注释),并执行php start.php reload * 然后观察一段时间workerman.log看是否有process_timeout异常 */ //declare(ticks=1); use \GatewayWorker\Lib\Gateway; /** * 主逻辑 * 主要是处理 onConnect onMessage onClose 三个方法 * onConnect 和 onClose 如果不需要可以不用实现并删除 */ class Events { /** * 当客户端连接时触发 * 如果业务不需此回调可以删除onConnect * * @param int $client_id 连接id */ public static function onConnect($client_id) { //global是设置全局变量的函数 global $num; // 向当前client_id发送数据 //Gateway::sendToClient($client_id, "Hello $client_id\r\n"); // 向所有人发送 // Gateway::sendToAll("$client_id login\r\n"); $data = json_encode(array('type'=>'init','client_id'=>$client_id)); echo "connect".++$num.":".$client_id."\n"; 发送数据到指定clientid里 Gateway::sendToClient($client_id,$data); } /** * 当客户端发来消息时触发 * @param int $client_id 连接id * @param mixed $message 具体消息 */ public static function onMessage($client_id, $message) { // 向所有人发送 $message_data = json_decode($message,true); if(!$message_data){ return; } switch($message_data['type']){ case "bind": $fromid = $message_data['fromid']; //绑定clientid到用户id里,发送消息通过用户id发送 Gateway::bindUid($client_id, $fromid); echo "datasend".$fromid."\n"; return; case "say": //解析字符串成html字符串 $text = nl2br(htmlspecialchars($message_data['data'])); $fromid = $message_data['fromid']; $toid = $message_data['toid']; $date=[ 'type'=>'text', 'data'=>$text, 'fromid'=>$fromid, 'toid'=>$toid, 'time'=>time() ]; echo "datasend".$fromid."\n"; echo "datasend".$toid."\n"; //传输数据到指定用户id Gateway::sendToUid($toid,json_encode($date)); return; } } /** * 当用户断开连接时触发 * @param int $client_id 连接id */ public static function onClose($client_id) { // 向所有人发送 echo "logout:".$client_id."\n"; } } ~~~ 功能到这里已经基本实现了,后面还会对消息进行数据库记录