1. 程式人生 > >swoole結合支持thinkphp 5.0版本

swoole結合支持thinkphp 5.0版本

task 設置 fin define num ech 文件內容 功能 改進

安裝swoole

pecl install swoole
修改PHP配置文件php.ini加入
extension=swoole.so

有可能不需要人工去加,安裝時自動加入進來了,

查看swoole擴展是否安裝好

/usr/local/php/bin/php -m

配制列表裏面如果有swoole的話,恭喜你安裝並配置swoole成功。

在index.php同級目錄下面新新建ws.php文件,文件內容以下

<?php
class Ws {
    CONST HOST = "0.0.0.0";
    CONST PORT = 9501;

    public
$ws = null; public function __construct() { $this->ws = new swoole_websocket_server(self::HOST, self::PORT); $this->ws->set( [ ‘worker_num‘ => 4,//打開的進程數 ‘daemonize‘=>0,//1守護進程,在後臺一直運行 ] );
//websocket繼承於http_service,所以擁有http_service服務器的所有函數 //http_service函數, $this->ws->on("start", [$this, ‘onStart‘]); $this->ws->on("workerstart", [$this, ‘onWorkerStart‘]);//此事件在Worker進程/Task進程啟動時發生。 $this->ws->on("request", [$this, ‘onRequest‘]);
$this->ws->on("task", [$this, ‘onTask‘]); $this->ws->on("finish", [$this, ‘onFinish‘]); //websocket函數 $this->ws->on("open", [$this, ‘onOpen‘]); $this->ws->on("message", [$this, ‘onMessage‘]); $this->ws->on("close", [$this, ‘onClose‘]); $this->ws->start();//開啟 } /** * @param $server */ public function onStart($server) { swoole_set_process_name("websocket");//修改進程名稱,非必要 } /** * @param $server * @param $worker_id */ public function onWorkerStart($server, $worker_id) { //swoole是cli運行,執行地址path會無法正確找到,所以把base.php裏面定義的常量提出來,設置為假, //註意:記住把源代碼base.php裏面的define(‘IS_CLI‘,false)代碼去掉(常量不能重復定義),在index.php裏面加入代碼:define(‘IS_CLI‘, PHP_SAPI == ‘cli‘ ? true : false); define(‘IS_CLI‘,false);// //當進程運行時,把框架代碼加載進來 // 定義應用目錄 define(‘APP_PATH‘, __DIR__ . ‘/../application/‘); // 加載框架裏面的文件 require __DIR__ . ‘/../thinkphp/base.php‘; } /** * request回調 * 當請求過來時,會調用此方法,調用thinkphp真正的執行邏輯 * @param $request * @param $response */ public function onRequest($request, $response) { //因為這些全局變量會在進程的內存裏面不變,所有每次請求到來先清空值。 if($request->server[‘request_uri‘] == ‘/favicon.ico‘) { $response->status(404); $response->end(); return ; } $_SERVER = []; if(isset($request->server)) { foreach($request->server as $k => $v) { $_SERVER[strtoupper($k)] = $v; } } if(isset($request->header)) { foreach($request->header as $k => $v) { $_SERVER[strtoupper($k)] = $v; } } $_GET = []; if(isset($request->get)) { foreach($request->get as $k => $v) { $_GET[$k] = $v; } } $_FILES = []; if(isset($request->files)) { foreach($request->files as $k => $v) { $_FILES[$k] = $v; } } $_POST = []; if(isset($request->post)) { foreach($request->post as $k => $v) { $_POST[$k] = $v; } } $_POST[‘http_server‘] = $this->ws;//把對像傳過去 ob_start(); try { // 執行應用並響應 think\App::run()->send(); }catch (\Exception $e) { // todo echo $e->getMessage(); } $res = ob_get_contents(); ob_end_clean(); $response->end($res); } /** * 監聽ws連接事件 * @param $ws * @param $request */ public function onOpen($ws, $request) { $ws->push($request->fd, "hello, welcome\n");//發送消息給客戶端 /* 與thinkphp框架結合 think\App::run();//如果不執行這行代碼,框架裏面很多功能用不了 //執類指定類裏面的指定方法 $obj=new \app\index\controller\Login(); $obj->action(); */ } /** * 接收客戶端傳過來的消息事件 * @param $ws * @param $frame */ public function onMessage($ws, $frame) { $msg=$frame->data;//接收客戶端傳過來的消息 $ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s")); } /** * ws客戶端關閉時調用事件 * @param $ws * @param $fd */ public function onClose($ws, $fd) { echo "clientid:{$fd}\n"; } /** * @param $serv * @param $taskId * @param $workerId * @param $data */ public function onTask($serv, $taskId, $workerId, $data) { // 分發 task 任務機制,讓不同的任務 走不同的邏輯 $obj = new app\common\lib\task\Task; $method = $data[‘method‘]; $flag = $obj->$method($data[‘data‘], $serv); /*$obj = new app\common\lib\ali\Sms(); try { $response = $obj::sendSms($data[‘phone‘], $data[‘code‘]); }catch (\Exception $e) { // todo echo $e->getMessage(); }*/ return $flag; // 告訴worker } /** * @param $serv * @param $taskId * @param $data */ public function onFinish($serv, $taskId, $data) { echo "taskId:{$taskId}\n"; echo "finish-data-sucess:{$data}\n"; } } new Ws();
因為tp裏面的全局變量會在進程的內存裏面不變,會導致執行地址path不更新,需要修改源代碼
修改框架源代碼thinkphp/library/think/Request.php,兩處地方,如下2圖:

技術分享圖片

技術分享圖片

上面是服務端websocket代碼,下面是客戶端JS
<script>
var wsServer = ‘ws://193.112.27.236:9501/index/login/a?cc=1‘; //websocket服務端地址,記住ws://不能去掉
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
    console.log("Connected to WebSocket server.");
	websocket.send(1111);//發送數據給服務器
};

//服務端關閉時調用
websocket.onclose = function (evt) {
    console.log("Disconnected");
};

//服務端向客戶端發送消息時調用
websocket.onmessage = function (evt) {
    console.log(‘Retrieved data from server: ‘ + evt.data);
};

//服務端報錯時調用
websocket.onerror = function (evt, e) {
    console.log(‘Error occured: ‘ + evt.data);
};
</script>

  註意:linux上面運行開啟服務時

php ws.php

以上命令可能會有問題,因為cli模式下運行的php 可能跟你項目運行的php版本跟配置文件不一樣

可以使用以下命令來保證準確:

技術分享圖片

查看是否啟動成功

技術分享圖片

修改代碼之後,需要殺死進程,重新啟動

技術分享圖片

swoole結合支持thinkphp 5.0版本