websocket服務(wù)能夠開啟成功,但是卻無法連接!
如果開啟的服務(wù)不走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");
// 創(chuàng)建一個Worker監(jiān)聽2346端口,使用websocket協(xié)議通訊
$ws_worker = new Worker("websocket://0.0.0.0:800");
$ws_worker->name = 'MyWorker';
// 啟動4個進(jìn)程對外提供服務(wù)
$ws_worker->count = 4;
// 當(dāng)收到客戶端發(fā)來的數(shù)據(jù)后返回hello $data給客戶端
$ws_worker->onMessage = function($connection, $data)
{
// 向客戶端發(fā)送hello $data
$connection->send($data);
};
// 運(yùn)行worker
Worker::runAll();
}
}
如果我沒理解錯的話,CI 是一個 Web 應(yīng)用框架,用 MVC 的方式來組織應(yīng)用邏輯。典型情況下,CI 的程序應(yīng)該是通過 web 容器來調(diào)用的,也就是常規(guī)的 PHP 應(yīng)用方式,用于處理短連接的 HTTP 請求。
而 WorkerMan 并不是跑在 Web 容器里的,它應(yīng)該是以 PHP-CLI 方式啟動,并長時間保持運(yùn)行的,用于處理 socket 長連接通信。
把 WorkerMan 放到 CI 框架里,似乎不是一個合適的用法。
@3368:也許可以考慮把你的業(yè)務(wù)代碼寫成比較通用的形式(不依賴于 CI 框架),然后在 CI 的 model 里面調(diào)用,這樣就比較容易重用到 WorkerMan 框架中。
當(dāng)然話說回來,原帖給出的代碼,如果是用 CLI 方式啟動入口文件,只要能運(yùn)行到 Worker::runAll() 這個地方,似乎也沒有什么理由不能正常處理 websocket 呀。不知樓主是怎么啟動程序的,啟動之后有沒有看到什么輸出?
其實(shí)原因我已經(jīng)找到,parseCommand方法,解析的是文件,而ci框架cli執(zhí)行的不是文件,而是路由到方法,比如php index.php websocket index start,這樣就會出問題。而不使用框架的話,php index.php start,這樣就沒問題。要改框架了,暫時沒想到好辦法
看來就是因?yàn)槁酚山馕龅膯栴},導(dǎo)致沒有執(zhí)行到 Worker::runAll()。
web 應(yīng)用框架一般都是依賴 web 容器提供的 $_GET、$_SERVER['REQUEST_URI'] 之類來進(jìn)行路由控制的,但 CLI 啟動時并沒有這些,所以一個比較取巧的辦法就是改動入口文件,手工設(shè)定 CI 框架路由解析所需要的相關(guān)參數(shù)。
@3346:因?yàn)槲疫@邊主題代碼是web的,現(xiàn)在websocket只是一個小功能,需要使用web里寫好的一些公共部分的東西,才想要集成的,所以入口文件這個還沒法改,哎