tp5使用workman的socket

927 阅读1分钟

1、安装workerman

composer require workerman/workerman

2、项目根目录新建一个文件,如 socket.php

将以下内写入此文件

#!/usr/bin/env php
<?php
define('APP_PATH', __DIR__ . '/application/');
define('BIND_MODULE','push/Socket');
// 加载框架引导文件
require __DIR__ . '/thinkphp/start.php';

3、新建socket类

application/push/controller/Socket.php

<?php
namespace app\push\controller;

use app\push\lib\SocketLib;
use Workerman\Lib\Timer;
use Workerman\Worker;

class Socket
{
    public function __construct()
    {
        $config = config('tcp');
        $worker = new Worker('tcp://' . $config['host'] . ':' . $config['port']);

        $worker->onWorkerStart = function(){

        };

        $worker->onMessage = function($connection, $data){
            //接收消息,记录日志
            SocketLib::set_file_log('message is : '. $data, 'message_' . date('Y-m-d'));
            $result = SocketLib::handle_reply($connection, $data);
            //发送消息,记录日志
            SocketLib::set_file_log('send is : '. $result, 'send_' . date('Y-m-d'));
            $connection->send($result);
        };

        //连接时,写日志
        $worker->onConnect = function($connection){
            SocketLib::set_file_log("new connection from ip " . $connection->getRemoteIp() . "\n");
        };

        //发生错误,写入日志
        $worker->onError = function(\Exception $exception){
            SocketLib::set_file_log('error is : '.  $exception->getMessage(), 'error_' . date('Y-m-d'));
        };

        Worker::runAll();
    }
}

4、新建SocketLib.php

application/push/lib/SocketLib.php

<?php
namespace app\push\lib;

use think\Exception;
use Workerman\Lib\Timer;

class SocketLib
{
    //订阅事件类型
    static $_sub_event_list = ['A', 'B', 'C', 'D', 'E', 'F'];
    /**
     * 处理订阅回复事件
     * @param object $con
     * @param string $content
     */
    public static function handle_reply($con, $content)
    {
        try {
            //解析上报内容,统一解析下
            $content = json_decode($content, true);
            $event = isset($content['event']) ? $content['event'] : '';
            //判断当前订阅事件是否合法
            if (in_array($event, self::$_sub_event_list)) {
                return self::$event($content); //根据不同的事件类型,执行相对应的方法
            } else {
                return self::fail($event, '订阅事件不合法');
            }
        } catch (Exception $e) {
            return self::fail($event, $e->getMessage());
        }
    }
    
    
    //订阅事件A
    public function A($content){
        //写业务逻辑
    }

    //订阅事件B
    public function A($content){
        //写业务逻辑
    }
    
    public static function timer($connection)
    {

        Timer::add(5, function() use($connection) {
            $device_id = $redis->lpop('topic_cabinet_IDQUE_list');
            if (! empty($device_id)) {
                //执行下发
                $result = TcpEvents::handle_reply($connection, '{"ORD":"IDQUE","SN":"'.$device_id.'"}');
                $connection->send($result);
            }
            $device_id = $redis->lpop('topic_cabinet_BUCKID_list');
            if (! empty($device_id)) {
                //执行下发
                $result = TcpEvents::handle_reply($connection, '{"ORD":"BUCKID","SN":"'.$device_id.'"}');
                $connection->send($result);
            }
        });
    }

    /**
     * 成功的返回信息
     */
    public static function success($event, $msg = 'success', $extra = [])
    {
        return json_encode(
            array_merge(
                [
                    "event"=> $event,
                    'msg' => $msg
                ],
                $extra
            ),
            JSON_UNESCAPED_UNICODE
        );
    }

    /**
     * 失败的返回信息
     */
    public static function fail($event, $msg = 'fail', $extra = [])
    {
        return json_encode(
            array_merge(
                [
                    "event"=> $event,
                    'msg' => $msg
                ],
                $extra
            ),
            JSON_UNESCAPED_UNICODE
        );
    }

    public static function set_file_log($message, $file = '')
    {
        try {
            $log_file = ROOT_PATH . 'runtime/log/socket/tcp_' . ($file ? $file : date('Y-m-d')) . '.log';
            $file_exists = file_exists($log_file) ? true : false;
            file_put_contents($log_file, 'time is : ' . date('Y-m-d H:i:s') . ' ' .$message. "\r\n", FILE_APPEND);
            if (! $file_exists) @chmod("/somedir/somefile", 0777);
        } catch (Exception $e) {
            $log_file = ROOT_PATH . 'runtime/log/socket/tcp_catch.log';
            $file_exists = file_exists($log_file) ? true : false;
            $message = 'catch message is : ' . $e->getMessage();
            file_put_contents($log_file, 'time is : ' . date('Y-m-d H:i:s') . ' ' .$message. "\r\n", FILE_APPEND);
            if (! $file_exists) @chmod("/somedir/somefile", 0777);
        }

        if (self::DEBUG) echo $message;
    }
}

附注:项目结构

application
    --push
        --controller/Socket.pph     
        --lib/SOcketLib.php
    socket.php