师院派记忆你的回忆
tp5和gateworer集成
  • 首页 > 开发语言
  • 作者:zhyu20
  • 2018年1月25日 15:31 星期四
  • 浏览:1092
  • 字号:
  • 评论:
  • 第一步:安装thinkpph程序包

    第二步:切换到根目录,使用composer require workerman/gateway-worker 安装Linux版本的gateway。(前提是你服务器安装了composer )

    http://www.workerman.net/workerman-chat 下载官方实例:workerman-chat  将文件夹内的applications\chat\Web\下的文件上传到:\public\static\index下

    第三部:在public目录下:新建server.php

    复制代码
    <?php // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: liu21st <liu21st@gmail.com>
    // +----------------------------------------------------------------------
    
    // [ 应用入口文件 ]
    
    // 定义应用目录 define('APP_PATH', __DIR__ . '/../application/'); define('BIND_MODULE','gateway/Run'); // 加载框架引导文件 require __DIR__ . '/../thinkphp/start.php';
    复制代码

    切换到:public目录下执行:php server.php start

    第四部:新建gateway模块 下建三个控制器:

    (1)Run.php


    <?php
    namespace app\gateway\controller;
    use think\Controller;
    use Workerman\Worker;
    use GatewayWorker\Register;
    use GatewayWorker\BusinessWorker;
    use GatewayWorker\Gateway;
    class Run
    {  public function __construct()      {  // 初始化register   new Register('text://0.0.0.0:1236');  //初始化 bussinessWorker 进程   $worker = new BusinessWorker();  $worker->name = 'RoomBusinessWorker';  $worker->count = 4;  $worker->registerAddress = '127.0.0.1:1236';  // 设置处理业务的类,此处制定Events的命名空间  $worker->eventHandler = '\app\gateway\controller\Events';  // 初始化 gateway 进程  $gateway = new Gateway("websocket://0.0.0.0:7272");  $gateway->name = 'RoomGateway';  $gateway->count = 4;  $gateway->lanIp = '127.0.0.1';  $gateway->startPort = 2900;  $gateway->registerAddress = '127.0.0.1:1236';  // 运行所有Worker; Worker::runAll();
    


    (2) Events.php

    复制代码
    namespace app\gateway\controller;
    use GatewayWorker\Lib\Gateway;
    use think\Controller;
    class Events extends Controller
    {
    	/**
         * 有消息时
         * @param integer $client_id 连接的客户端
         * @param mixed $message
         * @return void */
    	public static function onMessage($client_id, $message)
    	    {
    		// debug 
    		echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
    		// 客户端传递的是json数据 
    		$message_data = json_decode($message, true);
    		if(!$message_data)
    		        {
    			return ;
    		}
    		// 根据类型执行不同的业务 
    		switch($message_data['type'])
    		        {
    			// 客户端回应服务端的心跳 
    			case 'pong': return;
    			// 客户端登录 message格式: {type:login, name:xx, room_id:1} ,添加到客户端,广播给所有客户端xx进入聊天室 
    			case 'login': // 判断是否有房间号 if(!isset($message_data['room_id']))
    			{
    				throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
    			}
    			// 把房间号昵称放到session中 
    			$room_id = $message_data['room_id'];
    			$client_name = htmlspecialchars($message_data['client_name']);
    			$_SESSION['room_id'] = $room_id;
    			$_SESSION['client_name'] = $client_name;
    			// 获取房间内所有用户列表 
    			$clients_list = Gateway::getClientSessionsByGroup($room_id);
    			foreach($clients_list as $tmp_client_id=>$item)
    			                {
    				$clients_list[$tmp_client_id] = $item['client_name'];
    			}
    			$clients_list[$client_id] = $client_name;
    			// 转播给当前房间的所有客户端,xx进入聊天室 message {type:login, client_id:xx, name:xx} 
                $new_message = array('type'=>$message_data['type'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'time'=>date('Y-m-d H:i:s'));
    			Gateway::sendToGroup($room_id, json_encode($new_message));
    			Gateway::joinGroup($client_id, $room_id);
    			// 给当前用户发送用户列表 
    			$new_message['client_list'] = $clients_list;
    			Gateway::sendToCurrentClient(json_encode($new_message));
    			return;
    			// 客户端发言 message: {type:say, to_client_id:xx, content:xx}
    			case 'say': // 非法请求 
    			if(!isset($_SESSION['room_id']))
    			                {
    				throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
    			}
    			$room_id = $_SESSION['room_id'];
    			$client_name = $_SESSION['client_name'];
    			// 私聊
    			if($message_data['to_client_id'] != 'all')
    			                {
    				$new_message = array( 'type'=>'say',
    				                        'from_client_id'=>$client_id,
    				                        'from_client_name' =>$client_name,
    				                        'to_client_id'=>$message_data['to_client_id'],
    				                        'content'=>"<b>对你说: </b>".nl2br(htmlspecialchars($message_data['content'])),
    				                        'time'=>date('Y-m-d H:i:s'), );
    				Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
    				$new_message['content'] = "<b>你对".htmlspecialchars($message_data['to_client_name'])."说: </b>".nl2br(htmlspecialchars($message_data['content']));
    				return Gateway::sendToCurrentClient(json_encode($new_message));
    			}
    			$new_message = array( 'type'=>'say',
    			                    'from_client_id'=>$client_id,
    			                    'from_client_name' =>$client_name,
    			                    'to_client_id'=>'all',
    			                    'content'=>nl2br(htmlspecialchars($message_data['content'])),
    			                    'time'=>date('Y-m-d H:i:s'), );
    			return Gateway::sendToGroup($room_id ,json_encode($new_message));
    		}
    	}
    	/**
         * 当客户端断开连接时
         * @param integer $client_id 客户端id */
    	public static function onClose($client_id)
    	    {
    		// debug 
    		echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']}  client_id:$client_id onClose:''\n";
    		// 从房间的客户端列表中删除 
    		if(isset($_SESSION['room_id']))
    		        {
    			$room_id = $_SESSION['room_id'];
    			$new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
    			Gateway::sendToGroup($room_id, json_encode($new_message));
    		}
    	}
    	/**
         * 当用户连接时触发的方法
         * @param integer $client_id 连接的客户端
         * @return void */
    	public static function onConnect($client_id)
    	    {
    		Gateway::sendToClient($client_id, "Your client_id is $client_id");
    	}
    	/**
         * 当用户断开连接时触发的方法
         * @param integer $client_id 断开连接的客户端
         * @return void */
    	// public static function onClose($client_id)
    	//    {
    	//        Gateway::sendToAll("client[$client_id] logout\n");
    	//    } /**
    	* 当进程启动时
    	     * @param integer $businessWorker 进程实例 */ 
    	public static function onWorkerStart($businessWorker)
    	    {
    		echo "WorkerStart\n";
    	}
    	/**
         * 当进程关闭时
         * @param integer $businessWorker 进程实例 */
    	public static function onWorkerStop($businessWorker)
    	    {
    		echo "WorkerStop\n";
    	}
    }
    
    
    复制代码

    (3)index.php

    复制代码
    <?php
    namespace app\gateway\controller; use think\Controller; class Index extends Controller
    { public function index()
        { return $this->fetch();
        }
    }
    复制代码

     

    第五部:gateway模块下新建视图文件:

    复制代码
    <html><head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>workerman-chat PHP聊天室 Websocket(HTLM5/Flash)+PHP多进程socket实时推送技术</title>
      <link href="/static/index/css/bootstrap.min.css" rel="stylesheet">
      <link href="/static/index/css/style.css" rel="stylesheet">
        
      <script type="text/javascript" src="/static/index/js/swfobject.js"></script>
      <script type="text/javascript" src="/static/index/js/web_socket.js"></script>
      <script type="text/javascript" src="/static/index/js/jquery.min.js"></script>
    
      <script type="text/javascript"> if (typeof console == "undefined") {    this.console = { log: function (msg) {  } };} // 如果浏览器不支持websocket,会使用这个flash自动模拟websocket协议,此过程对开发者透明 WEB_SOCKET_SWF_LOCATION = "/static/index/swf/WebSocketMain.swf"; // 开启flash的websocket debug WEB_SOCKET_DEBUG = true; var ws, name, client_list={}; // 连接服务端 function connect() { // 创建websocket ws = new WebSocket("ws://"+document.domain+":7272"); // 当socket连接打开时,输入用户名 ws.onopen = onopen; // 当有消息时根据消息类型显示不同信息 ws.onmessage = onmessage; 
           ws.onclose = function() {
              console.log("连接关闭,定时重连");
              connect();
           };
           ws.onerror = function() {
               console.log("出现错误");
           };
        } // 连接建立时发送登录信息 function onopen()
        { if(!name)
            {
                show_prompt();
            } // 登录 var login_data = '{"type":"login","client_name":"'+name.replace(/"/g, '\\"')+'","room_id":"<?php echo isset($_GET['room_id']) ? $_GET['room_id'] : 1?>"}';
            console.log("websocket握手成功,发送登录数据:"+login_data);
            ws.send(login_data);
        }
    
        // 服务端发来消息时
        function onmessage(e)
        {
            console.log(e.data);
            var data = eval("("+e.data+")");
            switch(data['type']){
                // 服务端ping客户端
                case 'ping':
                    ws.send('{"type":"pong"}');
                    break;;
                // 登录 更新用户列表
                case 'login':
                    //{"type":"login","client_id":xxx,"client_name":"xxx","client_list":"[...]","time":"xxx"}
                    say(data['client_id'], data['client_name'],  data['client_name']+' 加入了聊天室', data['time']);
                    if(data['client_list'])
                    {
                        client_list = data['client_list'];
                    }
                    else
                    {
                        client_list[data['client_id']] = data['client_name']; 
                    }
                    flush_client_list();
                    console.log(data['client_name']+"登录成功");
                    break;
                // 发言
                case 'say':
                    //{"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}
                    say(data['from_client_id'], data['from_client_name'], data['content'], data['time']);
                    break;
                // 用户退出 更新用户列表
                case 'logout':
                    //{"type":"logout","client_id":xxx,"time":"xxx"}
                    say(data['from_client_id'], data['from_client_name'], data['from_client_name']+' 退出了', data['time']);
                    delete client_list[data['from_client_id']];
                    flush_client_list();
            }
        }
    
        // 输入姓名
        function show_prompt(){  
            name = prompt('输入你的名字:', '');
            if(!name || name=='null'){  
                name = '游客';
            }
        }  
    
        // 提交对话
        function onSubmit() {
          var input = document.getElementById("textarea");
          var to_client_id = $("#client_list option:selected").attr("value"); var to_client_name = $("#client_list option:selected").text();
          ws.send('{"type":"say","to_client_id":"'+to_client_id+'","to_client_name":"'+to_client_name+'","content":"'+input.value.replace(/"/g, '\\"').replace(/\n/g,'\\n').replace(/\r/g, '\\r')+'"}');
          input.value = "";
          input.focus();
        }
    
        // 刷新用户列表框
        function flush_client_list(){
            var userlist_window = $("#userlist"); var client_list_slelect = $("#client_list");
            userlist_window.empty();
            client_list_slelect.empty();
            userlist_window.append('<h4>在线用户</h4><ul>');
            client_list_slelect.append('<option value="all" id="cli_all">所有人</option>'); for(var p in client_list){
                userlist_window.append('<li id="'+p+'">'+client_list[p]+'</li>');
                client_list_slelect.append('<option value="'+p+'">'+client_list[p]+'</option>');
            }
            $("#client_list").val(select_client_id);
            userlist_window.append('</ul>');
        } // 发言 function say(from_client_id, from_client_name, content, time){
            $("#dialog").append('<div class="speech_item"><img src="http://lorempixel.com/38/38/?'+from_client_id+'" class="user_icon" /> '+from_client_name+' <br> '+time+'<div style="clear:both;"></div><p class="triangle-isosceles top">'+content+'</p> </div>');
        }
    
        $(function(){
            select_client_id = 'all';
            $("#client_list").change(function(){
                 select_client_id = $("#client_list option:selected").attr("value");
            });
        }); </script>
    </head>
    <body onload="connect();">
        <div class="container">
            <div class="row clearfix">
                <div class="col-md-1 column">
                </div>
                <div class="col-md-6 column">
                   <div class="thumbnail">
                       <div class="caption" id="dialog"></div>
                   </div>
                   <form onsubmit="onSubmit(); return false;">
                        <select style="margin-bottom:8px" id="client_list">
                            <option value="all">所有人</option>
                        </select>
                        <textarea class="textarea thumbnail" id="textarea"></textarea>
                        <div class="say-btn"><input type="submit" class="btn btn-default" value="发表" /></div>
                   </form>
                   <div>
                   &nbsp;&nbsp;&nbsp;&nbsp;<b>房间列表:</b>(当前在&nbsp;房间<?php echo isset($_GET['room_id'])&&intval($_GET['room_id'])>0 ? intval($_GET['room_id']):1; ?>)<br>
                   &nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=1">房间1</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=2">房间2</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=3">房间3</a>&nbsp;&nbsp;&nbsp;&nbsp;<a href="/?room_id=4">房间4</a>
                   <br><br>
                   </div>
                   <p class="cp">PHP多进程+Websocket(HTML5/Flash)+PHP Socket实时推送技术&nbsp;&nbsp;&nbsp;&nbsp;Powered by <a href="http://www.workerman.net/workerman-chat" target="_blank">workerman-chat</a></p>
                </div>
                <div class="col-md-3 column">
                   <div class="thumbnail">
                       <div class="caption" id="userlist"></div>
                   </div>
                   <a href="#" target="_blank"><img style="width:252px;margin-left:5px;" src="/static/index/img/workerman-todpole.png"></a>
                </div>
            </div>
        </div>
    </body>
    </html>
    复制代码

    见目录:

     

     最终效果:

    记得在linux系统中把使用的端口允许访问

      您阅读这篇文章共花了:  
    二维码加载中...
    本文作者:zhyu20      文章标题: tp5和gateworer集成
    本文地址:http://blog.shiyuanpai.com/kaifayuyan/848.html
    版权声明:若无注明,本文皆为“师院博客”原创,转载请保留文章出处。
    • blogger
    返回顶部| 首页| 手气不错| 后花园

    Copyright © 2014-2016 师院博客   皖ICP备14013862号

    sitemap