欢迎访问WDPHP素材源码站!夜深了,还不睡吗?
您好,游客 <游客> [ 马上登录 | 注册帐号 ] 帮助中心
当前位置:首页 > 教程 > 编程教程 > 

THINKPHP5+GatewayWorker+Workerman 开发在线客服系统
栏目分类:编程教程    发布日期:2017-11-26    浏览次数:4452次     收藏

WDPHP素材源码最近在自主开发在线客服系统,开发采用THINKPHP5+GatewayWorker+Workerman 希望对大家有所帮助

相关介绍

 workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及libevent事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。

GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等

ThinkPHP V5.0是一个为API开发而设计的高性能框架——是一个颠覆和重构版本,采用全新的架构思想,引入了很多的PHP新特性,优化了核心,减少了依赖,实现了真正的惰性加载,支持composer,并针对API开发做了大量的优化。 ThinkPHP5是一个全新的里程碑版本,包括路由、日志、异常、模型、数据库、模板引擎和验证等模块都已经重构,不适合原有3.2项目的升级,请慎重考虑商业项目升级,但绝对是新项目的首选(无论是WEB还是API开发),而且最好是忘记3.2版本的思维习惯,重新理解TP5。

前置工作

开发是LINUX环境进行,使用composer安装相关类库。

推荐PHP5.6

WINDOWS用户请替换为workerman-for-win 和 GatewayWorker-for-win

1、安装ThinkPHP

2、在安装目录下

composer require workerman/workerman
composer require workerman/gateway-worker

程序目录截图

开始关键部分

1、添加入口文件
在项目根目录 新增启动服务文件server.php,用于在cli模式下运行

#!/usr/bin/env php
<?php
ini_set('display_errors', 'on');
if(strpos(strtolower(PHP_OS), 'win') === 0)
{
    exit("start.php not support windows.\n");
}
// 检查扩展
if(!extension_loaded('pcntl'))
{
    exit("Please install pcntl extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}
if(!extension_loaded('posix'))
{
    exit("Please install posix extension. See http://doc3.workerman.net/appendices/install-extension.html\n");
}


define('APP_PATH', __DIR__ . '/apps/');

define('BIND_MODULE','push/Run');

// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';

控制器:app\push\controller\Run

<?php
namespace app\push\controller;

use Workerman\Worker;
use GatewayWorker\Register;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;


class Run{
  /**
     * 构造函数
     * @access public
     */
    public function __construct(){
		
		//由于是手动添加,因此需要注册命名空间,方便自动加载,具体代码路径以实际情况为准
        \think\Loader::addNamespace([
            'Workerman' => VENDOR_PATH . 'Workerman/workerman',
            'GatewayWorker' =>VENDOR_PATH . 'Workerman/gateway-worker/src',
        ]);
		
        //初始化各个GatewayWorker
		//初始化register
		new Register('text://0.0.0.0:1238');
		 
		 //初始化 bussinessWorker 进程
		$worker = new BusinessWorker();
		$worker->name = 'WebIMBusinessWorker';
		$worker->count = 4;
		$worker->registerAddress = '127.0.0.1:1238';
		
		//设置处理业务的类,此处制定Events的命名空间
		$worker->eventHandler = '\app\push\controller\Events';
		
		// 初始化 gateway 进程
		$gateway = new Gateway("websocket://0.0.0.0:8282");
		$gateway->name = 'WebIMGateway';
		$gateway->count = 4;
		$gateway->lanIp = '127.0.0.1';
		$gateway->startPort = 2900;
		$gateway->registerAddress = '127.0.0.1:1238';
		 
		 //运行所有Worker;
		Worker::runAll();
    }
}

控制器:app\push\controller\Events
Events控制器负责业务处理

<?php
namespace app\push\controller;

use GatewayWorker\Lib\Gateway;
/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events{
	/**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $data 具体消息
    */
    public static function onMessage($client_id, $data){
       $message = json_decode($data, true);
       $message_type = $message['type'];
	
       switch($message_type) {
           case 'init':
               // uid
               $uid = $message['id'];
               // 设置session
               $_SESSION = [
                   'username' => $message['username'],
                   'avatar'   => isset($message['avatar'])?$message['avatar']:'',
                   'id'       => $uid,
                   'sign'     => $message['sign'],
				   'type'	  => $type, 
               ];

               // 将当前链接与uid绑定
               Gateway::bindUid($client_id, $uid);
               // 通知当前客户端初始化
               $init_message = array(
                   'message_type' => 'init',
                   'id'           => $uid,
               );
               Gateway::sendToClient($client_id, json_encode($init_message));

               return;
               break;
           case 'chatMessage':
               // 聊天消息
               $type = $message['data']['to']['type'];
               $to_id = $message['data']['to']['id'];
               $uid = $_SESSION['id'];
 
               $chat_message = [
                    'message_type' => 'chatMessage',
                    'data' => [
                        'username' => $_SESSION['username'],
                        'avatar'   => $_SESSION['avatar'],
                        'id'       => $type === 'friend' ? $uid : $to_id,
                        'type'     => $type,
                        'content'  => htmlspecialchars($message['data']['mine']['content']),
                        'timestamp'=> time()*1000,
                    ]
               ];
         
               return Gateway::sendToUid($to_id, json_encode($chat_message));

               break;
           case 'hide':
           case 'online':
               $status_message = [
                   'message_type' => $message_type,
                   'id'           => $_SESSION['id'],
               ];
               $_SESSION['online'] = $message_type;
               Gateway::sendToAll(json_encode($status_message));
               return;
               break;
           case 'ping':
               return;
           default:
               echo "unknown message $data" . PHP_EOL;
       }
    }

    /**
     * 当客户端连接时触发
     * 如果业务不需此回调可以删除onConnect
     * 
     * @param int $client_id 连接id
     */
    public static function onConnect($client_id)
    {

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public static function onClose($client_id){
       $logout_message = [
           'message_type' => 'logout',
           'id'           => $_SESSION['id']
       ];
       Gateway::sendToAll(json_encode($logout_message));
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public static function onError($client_id, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public static function onWorkerStart($worker)
    {

    }
}

启动程序

SSH执行命令: >/server/php/56/bin /www/webim_top/server.php start
需要将 /server/php/56/bin 改为你的PHP执行路径
将 /www/webim_top/server.php 改为你的server.php路径


启动成功后的截图:

启动与停止

注意Workerman启动停止等命令都是在命令行中完成的。

启动

以debug(调试)方式启动

>/server/php/56/bin /www/webim_top/server.php start>

以daemon(守护进程)方式启动

>/server/php/56/bin /www/webim_top/server.php start -d>

停止

>/server/php/56/bin /www/webim_top/server.php stop>

重启

>/server/php/56/bin /www/webim_top/server.php restart>

平滑重启

>/server/php/56/bin /www/webim_top/server.php reload>

查看状态

>/server/php/56/bin /www/webim_top/server.php status>

查看连接状态(需要Workerman版本>=3.5.0)

结束语

管理端采用的是WDPHP内容管理框架开发,目前程序还在开发中,任重而道远!
先贴几个图给大家预览下:

用户的管理端

网站管理后台:

客服登录界面:

客服管理界面:


声明:本文为原创文章,如需转载,请注明来源 WDPHP.COM 并保留原文链接:http://wdphp.com/detail/1507.html
评论5
头像 游客
友情提示:评论成功赠送5积分(每日前3次),刷评论扣8积分!
  • 头像 4楼
    2018年04月25日
    panli
    写的确实很详细!
  • 头像 板凳
    2018年04月21日
    lgc137
    最新版tp5,配置各种出错,有时间的话更新下,万分感谢!
  • 头像 椅子
    2017年12月15日
    duanwangye
    我把 命名空间改成 GatewayWorker\src\Register 就可以找到 但是不管怎么改 ‘GatewayWorker\Protocols\GatewayProtocol’ 这个文件一直找不到 当我调用 Gateway 的 时候
    1
    wdphp

    1、注意workerman 是通过 composer安装的
    2、use 是否已引入相关文件
    3、你的文件路径是不是和我的示例一致
    或者加下QQ群:17540504 ,在群里聊

  • 头像 沙发
    2017年12月15日
    duanwangye
    我一直报找不到 文件的错误 class ‘GatewayWorker\Register’ not found
Copyright © 2016-2018 wdphp.com 版权所有   本站由WDPHP网站管理系统强力驱动  陕ICP备16002142号
网站首页 | 交流社区 | 关于我们 | 仿站定制 | 积分获取 | 广告投放 | 虚拟主机
特效 资源 源码 模板 教程 站长