有人在ci框架用过workerman吗,开启的websocket无法访问

一直在KO

websocket服务能够开启成功,但是却无法连接!
如果开启的服务不走ci的入口文件,则可以访问,一走ci框架的入口文件,就无法访问,很纳闷
附上代码:

<?php
use Workerman\Worker;

defined('BASEPATH') OR exit('No direct script access allowed');

class Websocket extends CI_Controller {

    public function __construct(){
        parent::__construct();
    }

    public function index(){
        //require_once __DIR__ . '/Autoloader.php';
        require_once(APPPATH."libraries/Workerman/Autoloader.php");

        // 创建一个Worker监听2346端口,使用websocket协议通讯
        $ws_worker = new Worker("websocket://0.0.0.0:800");
        $ws_worker->name = 'MyWorker';
        // 启动4个进程对外提供服务
        $ws_worker->count = 4;

        // 当收到客户端发来的数据后返回hello $data给客户端
        $ws_worker->onMessage = function($connection, $data)
        {
            // 向客户端发送hello $data
            $connection->send($data);
        };

        // 运行worker
        Worker::runAll();
    }
}
5133 2 1
2个回答

maq

不理解为啥要用 CI 框架来启动 WorkerMan……

  • 一直在KO 2018-01-30

    因为项目需要啊,项目其他部分全部都是ci写的,现在只有一小部分需要websocket,放在一起好点

maq

如果我没理解错的话,CI 是一个 Web 应用框架,用 MVC 的方式来组织应用逻辑。典型情况下,CI 的程序应该是通过 web 容器来调用的,也就是常规的 PHP 应用方式,用于处理短连接的 HTTP 请求。

而 WorkerMan 并不是跑在 Web 容器里的,它应该是以 PHP-CLI 方式启动,并长时间保持运行的,用于处理 socket 长连接通信。

把 WorkerMan 放到 CI 框架里,似乎不是一个合适的用法。

  • 一直在KO 2018-01-30

    话是这么说,但是我项目中需要使用到mvc框架里我已经写好的model,如果能调用不是更好吗,不然就只能另外重写

  • maq 2018-01-30

    @3368:也许可以考虑把你的业务代码写成比较通用的形式(不依赖于 CI 框架),然后在 CI 的 model 里面调用,这样就比较容易重用到 WorkerMan 框架中。

  • maq 2018-01-30

    当然话说回来,原帖给出的代码,如果是用 CLI 方式启动入口文件,只要能运行到 Worker::runAll() 这个地方,似乎也没有什么理由不能正常处理 websocket 呀。不知楼主是怎么启动程序的,启动之后有没有看到什么输出?

  • 一直在KO 2018-01-30

    其实原因我已经找到,parseCommand方法,解析的是文件,而ci框架cli执行的不是文件,而是路由到方法,比如php index.php websocket index start,这样就会出问题。而不使用框架的话,php index.php start,这样就没问题。要改框架了,暂时没想到好办法

  • maq 2018-01-30

    看来就是因为路由解析的问题,导致没有执行到 Worker::runAll()。
    web 应用框架一般都是依赖 web 容器提供的 $_GET、$_SERVER['REQUEST_URI'] 之类来进行路由控制的,但 CLI 启动时并没有这些,所以一个比较取巧的办法就是改动入口文件,手工设定 CI 框架路由解析所需要的相关参数。

  • 一直在KO 2018-01-30

    @3346:因为我这边主题代码是web的,现在websocket只是一个小功能,需要使用web里写好的一些公共部分的东西,才想要集成的,所以入口文件这个还没法改,哎

  • maq 2018-01-30

    很简单啊,另外写一个 index2.php 就行了嘛,反正是给 CLI 专用的。

  • tianhuo1990 2018-09-18

    @3346:请问通过在$worker = new Worker(); 初始化时在代码里控制传入start stop 之类的命令吗

  • liujian 2018-12-05

    我最近也是用这个框架来看 刚入手 还很多不太懂 能否交流一下

年代过于久远,无法发表回答
🔝