Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in /webData/hua/www.ascwh.com/var/Typecho/Feed.php on line 367
ASCWH - websocket 2020-03-05T16:41:00+08:00 Typecho https://www.ascwh.com/feed/atom/tag/websocket/ <![CDATA[thinkphp6.0 + Workerman+ GatewayWorker websocket通讯 ]]> https://www.ascwh.com/351.html 2020-03-05T16:41:00+08:00 2020-03-05T16:41:00+08:00 ASCWH https://www.ascwh.com 毫无疑问 重点在 Workerman
Workerman是一款纯PHP开发的开源高性能的PHP socket 服务框架。

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

ThinkPHP 手册中有部分在框架中的使用说明

首先通过 composer 安装

composer require topthink/think-worker

次扩展中说明了 两种启动方式

使用Workerman作为HttpServer

php think worker

SocketServer

php think worker:server

其他按照文档配置足够

或者按照 Workerman 手册 进行配置

说到这好像没有 GatewayWorker 的影子 如果不使用 GatewayWorker 也可以不进行安装 单独安装workerman 也可以 ,同时 topthink/think-worker ThinkPHP 官方扩展包一样可以不用安装,
如果使用 官方扩展包 以及 GatewayWorker 的话 怎么用呢 ![]![1583398260914.jpg]1583398226142.jpg
源码中使用命令 的只是文档没有说明
使用 php think worker:gateway 启动 扩展中的 GatewayWorker 即可
![]![1583398260914.jpg]![1583398226142.jpg]1583398260914.jpg

之后只需要配置 gateway_worker.php配置文件中配置
![]1583398282617.jpg
自定义业务处理就好了文件中都有说明,简单的很

]]>
<![CDATA[ThinkPHP5.1+ Swoole 实现 websocket]]> https://www.ascwh.com/338.html 2019-11-25T21:17:00+08:00 2019-11-25T21:17:00+08:00 ASCWH https://www.ascwh.com Swoole

Swoole是一个面向生产环境的 PHP 异步网络通信引擎。使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。

安装
首先按照Swoole官网说明安装swoole扩展,然后安装think-swoole扩展。

composer require topthink/think-swoole=2.0.*

安装之后会在 config 目录下生成两个配置文件
swoole.php
swoole_server.php
两者 作用不用 http 跟 socket
使用 socket 看 swoole_server.php
这是默认配置

return [
    // 扩展自身配置
    'host'         => '0.0.0.0', // 监听地址
    'port'         => 9501, // 监听端口
    'type'         => 'socket', // 服务类型 支持 socket http server
    'mode'         => SWOOLE_PROCESS,
    'socket_type'  => SWOOLE_SOCK_TCP,

    // 可以支持swoole的所有配置参数
    'daemonize'    => false,

    // 事件回调定义
    'onOpen'       => function ($server, $request) {
        echo "server: handshake success with fd{$request->fd}\n";
    },

    'onMessage'    => function ($server, $frame) {
        echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
        $server->push($frame->fd, "this is server");
    },

    'onRequest'    => function ($request, $response) {
        $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
    },

    'onClose'      => function ($ser, $fd) {
        echo "client {$fd} closed\n";
    },
];

也可自行定义

return [
    'swoole_class'    =>    'socket\Swoole\PustServer',
];

自定义类需继承 \think\swoole\Server
支持响应事件

['Start', 'Shutdown', 'WorkerStart', 'WorkerStop', 'WorkerExit', 'Connect', 'Receive', 'Packet', 'Close', 'BufferFull', 'BufferEmpty', 'Task', 'Finish', 'PipeMessage', 'WorkerError', 'ManagerStart', 'ManagerStop', 'Open', 'Message', 'HandShake', 'Request']

简单的 DEMO


namespace socket\Swoole;

use \think\swoole\Server;
use socket\Swoole\libs\MessageHandler;

class PustServer extends Server {


    protected $host       = '0.0.0.0'; //监听所有地址
    protected $port       = 9501; //监听9501端口
    protected $serverType = 'socket';
    protected $option     = [
        'worker_num'               => 4, //设置启动的Worker进程数
        'daemonize'                => false, //守护进程化(上线改为true)
        'backlog'                  => 128, //Listen队列长度
        'dispatch_mode'            => 2, //固定模式,保证同一个连接发来的数据只会被同一个worker处理

        //心跳检测:每60秒遍历所有连接,强制关闭10分钟内没有向服务器发送任何数据的连接
        'heartbeat_check_interval' => 60,
        'heartbeat_idle_time'      => 600
    ];

    private $messageHandler;

    /**
     * @title init 启动之前执行
     */
    protected function init() {
        parent::init();

    }

    /**
     * @title onWorkerStart 此事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用
     */
    public function onWorkerStart() {
        $this->messageHandler = new MessageHandler();
    }


    /**
     * @title onOpen 建立连接时回调函数
     *
     * @param $server
     * @param $req
     */
    public function onOpen($server, $request) {
        echo "server: handshake success with fd{$request->fd}\n";
    }

    /**
     * @title onMessage 接收数据时回调函数
     *
     * @param $server
     * @param $frame
     */
    public function onMessage($server, $frame) {
        // 重新执行 WorkerStart 不再需要在此命令重启 用户开发模式
        $this->swoole->reload();

        $data = json_decode($frame->data, true);
        $fd   = $frame->fd;

        if (empty($data) && !is_object($data)) {
            //仅推送给当前连接用户
            $server->push($fd, json_encode(['error' => 422, 'msg' => '参数错误']));
        }

        if (method_exists($this->messageHandler, $data['act'])) {
            call_user_func([$this->messageHandler, $data['act']], $server, $frame);
        }
    }

    /**
     * @title onClose 连接关闭时回调函数
     *
     * @param $server
     * @param $fd
     */
    public function onClose($server, $fd) {
        echo "标识{$fd}关闭了连接\n";
    }


}

messageHandler 为自定义处理逻辑

namespace socket\Swoole\libs;

class MessageHandler {

    public function single($server, $frame) {
        //仅推送给当前连接用户
        $server->push($frame->fd, json_encode(['OK']));
    }

    /**
     * @title group
     *
     * @param $server
     * @param $frame
     */
    public function group($server, $frame) {
        //推送给全部连接用户
        foreach ($server->connections as $fd) {
            $server->push($fd, json_encode([$fd . '===>OK']));
        }
    }
}

客户端 websocket 自行处理 可以自行定义客户端认证等操作 自行定义 json 或 get 形式

]]>