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();
}
}
不理解为啥要用 CI 框架来启动 WorkerMan……
因为项目需要啊,项目其他部分全部都是ci写的,现在只有一小部分需要websocket,放在一起好点
如果我没理解错的话,CI 是一个 Web 应用框架,用 MVC 的方式来组织应用逻辑。典型情况下,CI 的程序应该是通过 web 容器来调用的,也就是常规的 PHP 应用方式,用于处理短连接的 HTTP 请求。
而 WorkerMan 并不是跑在 Web 容器里的,它应该是以 PHP-CLI 方式启动,并长时间保持运行的,用于处理 socket 长连接通信。
把 WorkerMan 放到 CI 框架里,似乎不是一个合适的用法。
话是这么说,但是我项目中需要使用到mvc框架里我已经写好的model,如果能调用不是更好吗,不然就只能另外重写
@3368:也许可以考虑把你的业务代码写成比较通用的形式(不依赖于 CI 框架),然后在 CI 的 model 里面调用,这样就比较容易重用到 WorkerMan 框架中。
当然话说回来,原帖给出的代码,如果是用 CLI 方式启动入口文件,只要能运行到 Worker::runAll() 这个地方,似乎也没有什么理由不能正常处理 websocket 呀。不知楼主是怎么启动程序的,启动之后有没有看到什么输出?
其实原因我已经找到,parseCommand方法,解析的是文件,而ci框架cli执行的不是文件,而是路由到方法,比如php index.php websocket index start,这样就会出问题。而不使用框架的话,php index.php start,这样就没问题。要改框架了,暂时没想到好办法
看来就是因为路由解析的问题,导致没有执行到 Worker::runAll()。
web 应用框架一般都是依赖 web 容器提供的 $_GET、$_SERVER['REQUEST_URI'] 之类来进行路由控制的,但 CLI 启动时并没有这些,所以一个比较取巧的办法就是改动入口文件,手工设定 CI 框架路由解析所需要的相关参数。
@3346:因为我这边主题代码是web的,现在websocket只是一个小功能,需要使用web里写好的一些公共部分的东西,才想要集成的,所以入口文件这个还没法改,哎
很简单啊,另外写一个 index2.php 就行了嘛,反正是给 CLI 专用的。
@3346:请问通过在$worker = new Worker(); 初始化时在代码里控制传入start stop 之类的命令吗
我最近也是用这个框架来看 刚入手 还很多不太懂 能否交流一下