開發文檔:http://doc2.workerman.net/
下載服務器端安裝文件:
有windows版和linux版兩個版本,我下載的linux版,在windows上也可以運行。
打開后有這些文件:
把這個文件放在服務器上或者項目中都可以,需要運行的就是最后一個start_for_win.bat文件。
運行成功。
修改start_gateway.php文件:
1 <?php 2 /** 3 * This file is part of workerman. 4 * 5 * Licensed under The MIT License 6 * For full copyright and license information, please see the MIT-LICENSE.txt 7 * Redistributions of files must retain the above copyright notice. 8 * 9 * @author walkor<walkor@workerman.net> 10 * @copyright walkor<walkor@workerman.net> 11 * @link http://www.workerman.net/ 12 * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 */ 14 use \Workerman\Worker; 15 use \Workerman\WebServer; 16 use \GatewayWorker\Gateway; 17 use \GatewayWorker\BusinessWorker; 18 use \Workerman\Autoloader; 19 20 // 自動加載類 21 require_once __DIR__ . '/../../vendor/autoload.php'; 22 23 // gateway 進程,這里使用Text協議,可以用telnet測試 24 $gateway = new Gateway("websocket://0.0.0.0:8282"); 25 // gateway名稱,status方便查看 26 $gateway->name = 'YourAppGateway'; 27 // gateway進程數 28 $gateway->count = 4; 29 // 本機ip,分布式部署時使用內網ip 30 $gateway->lanIp = '127.0.0.1'; 31 // 內部通訊起始端口,假如$gateway->count=4,起始端口為4000 32 // 則一般會使用4000 4001 4002 4003 4個端口作為內部通訊端口 33 $gateway->startPort = 2900; 34 // 服務注冊地址 35 $gateway->registerAddress = '127.0.0.1:1238'; 36 37 // 心跳間隔 38 $gateway->pingInterval = 60; 39 // 心跳數據 40 $gateway->pingData = '{"type":"ping"}'; 41 42 /* 43 // 當客戶端連接上來時,設置連接的onWebSocketConnect,即在websocket握手時的回調 44 $gateway->onConnect = function($connection) 45 { 46 $connection->onWebSocketConnect = function($connection , $http_header) 47 { 48 // 可以在這里判斷連接來源是否合法,不合法就關掉連接 49 // $_SERVER['HTTP_ORIGIN']標識來自哪個站點的頁面發起的websocket鏈接 50 if($_SERVER['HTTP_ORIGIN'] != 'http://kedou.workerman.net') 51 { 52 $connection->close(); 53 } 54 // onWebSocketConnect 里面$_GET $_SERVER是可用的 55 // var_dump($_GET, $_SERVER); 56 }; 57 }; 58 */ 59 60 // 如果不是在根目錄啟動,則運行runAll方法 61 if(!defined('GLOBAL_START')) 62 { 63 Worker::runAll(); 64 }
第24行,把tcp協議改為websocket協議;
第38行和40行,設置服務器向客戶端發送的心跳時間,檢測客戶端是否連接,未連接將會斷開。
下面的內容都是默認注釋掉的,根據自己的需要打開或者修改。
再次運行start_for_win.bat文件:
協議就變為websocket協議了,現在就可以做項目內的操作了。
還需要再下載一個文件:https://github.com/walkor/GatewayClient
把這幾個文件放進thinkphp的extend文件夾下(我用的是thinkphp5.0版本):
在Gateway.php的文件中方法幾乎都寫好了。
寫了一個簡單的前端頁面:
1 <!DOCTYPE html> 2 <html lang="zh"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title></title> 8 </head> 9 <body> 10 <ul id="msgUl"> 11 <li>ws://127.0.0.1:8282</li> 12 </ul> 13 <input type="" name="" id="sendValue" value="" /> 14 <button type="button" id="sendButton">發送</button> 15 16 <div style="margin-top: 100px"> 17 {volist name="msg" id="vo" empty="這里沒有數據" key ='s'} 18 <br/> 19 <span>{$vo.user_name}:</span> 20 <span>{$vo.msg}</span> 21 <span>{$vo.createtime}</span> 22 <br/> 23 {/volist} 24 </div> 25 26 <script src="http://www.zhihuapinpai.com/static/index/js/jquery-1.11.3.min.js"></script> 27 <script> 28 // var ws = new WebSocket("ws://123.56.216.232:8282"); 29 var ws = new WebSocket("ws://127.0.0.1:8282"); 30 31 ws.onopen = function() { 32 $('#msgUl').append('<li>已連接上...</li>') 33 sendValue(); 34 }; 35 36 ws.onmessage = function(evt) { 37 $('#msgUl').append('<li>接收到:' + evt.data + '</li>') 38 var obj = JSON.parse(evt.data); 39 if (obj.type == 'onConnect') { 40 // 連接成功 41 $('#msgUl').append('<li>client_id:' + obj.client_id + '</li>') 42 $.ajax({ 43 type:"POST", 44 url:"/index.php/api/Index/user_bind", 45 data:{ 46 client_id:obj.client_id 47 }, 48 dataType: "html", 49 success: function(data){ 50 console.log('成功') 51 } 52 }); 53 } else if (obj.type == 'ping') { 54 // 心跳檢測 不做任何處理 55 } else if (obj.type == 'chatGroup') { 56 // 群組聊天 57 $('#msgUl').append('<li>接收到:' + evt.data + '</li>') 58 } 59 }; 60 61 ws.onclose = function() { 62 // console.log('連接已關閉...'); 63 $('#msgUl').append('<li>連接已關閉...</li>') 64 }; 65 66 function sendValue() { 67 $('#sendButton').click(function() { 68 var thisValue = $('#sendValue').val(); 69 if (thisValue) { 70 ws.send(thisValue); 71 $('#msgUl').append('<li>發送數據:' + thisValue + '</li>') 72 $.get("/index.php/api/Index/send_msg/msg/"+thisValue,function (data,status) { 73 console.log('成功:'+thisValue) 74 }); 75 } 76 }) 77 } 78 </script> 79 </body> 80 </html>
第42—52行把client_id傳到后台,與用戶表中用戶進行綁定。
后台代碼:
1 <?php 2 namespace app\api\controller; 3 use think\Controller; 4 use GatewayClient\Gateway; 5 use think\Db; 6 7 8 class Index extends Controller 9 { 10 11 public function websocket(){ 12 $where=[]; 13 $user_id=1; 14 $where['from_id|to_id']=$user_id; 15 $msg=Db::name('msg')->where($where)->select(); 16 foreach ($msg as $key=>$val){ 17 $msg[$key]['createtime']=date('Y-m-d H:i:s',$val['createtime']); 18 $msg[$key]['user_name']=Db::name('user')->where(['id'=>$val['from_id']])->value('name'); 19 } 20 $this->assign('msg',$msg); 21 return view(); 22 } 23 24 //綁定用戶 25 public function user_bind($user_id=1){ 26 //$user_id=1; //發送人用戶id 27 $client_id = input('post.client_id'); 28 // $user=Db::name('user')->where(['id'=>$user_id])->find(); 29 Gateway::bindUid($client_id, 1); 30 return $client_id; 31 } 32 33 //發送信息 34 public function send_msg(){ 35 $msg=input('msg'); 36 if($msg){ 37 $data=[ 38 'msg'=>$msg, 39 'from_id'=>1, 40 'to_id'=>2, 41 'createtime'=>time() 42 ]; 43 Db::name('msg')->insert($data); 44 Gateway::sendToUid(1,$msg); 45 Gateway::sendToUid(2,$msg); 46 } 47 return 'success'; 48 } 49 50 }
發送消息存入數據庫,頁面顯示即可。