swoole +tp5框架(thinkphp5+) 接入方法

本文系麥子時光原創,轉載請注明出處,謝謝

http://www.lxweimin.com/p/ff6ec1e143cb

不要用下面方法?


看下 thinkphp 的入口文件? index.php?

自動加載過程 非常的 溜 。。。。

我們自己建立一個 專門為 swoole 啟動用的

入口文件 為了體現 這個文件放置的隨意性 我們把

它建在 和 app 平級的目錄中 ,且叫叫 tasktest.php


從index.php 拷貝配置??

define('APP_PATH', __DIR__ . '/app/');

// 下面? 這個最 主要的配置? 就是 綁定 模塊到 指定 swoole 啟動的? 文件? 名字隨意? 對應就好

define('BIND_MODULE','core/Sio');??

define('ROOT_PATH', __DIR__ . '/');

// 加載框架引導文件

require __DIR__ . '/thinkphp/start.php';

這里我們 看下 對應的綁定模塊 core /sio


// 下面是我自己的業務 代碼?



整體結構


構造函數

其他三個函數

觸發相關 業務 這已經是swoole 內部的原理了 ,此處不贅述,只是這里可以利用框架的各種函數和簡單的異步內存共享

由于動用了task?

不要忘了finish

當然 還要用到clonse

onclonse 部分

現在 只要 運行?

運行示例
歡迎 微信交流


本文系麥子時光原創,轉載請注明出處,謝謝

http://www.lxweimin.com/p/ff6ec1e143cb

app\core\controller\sio

部分 源碼分享


<?php

namespace app\core\controller;

use Swoole\Server;

use think\Controller;

use think\Db;

class Sio? extends Controller

{

protected $port = 9052;

? ? private $serv;

? ? private $db_config = [];

? ? private $redis_server = "127.0.0.1";

? ? private $redis_port = "6379";

? ? private $redis_pwd = "";

? ? private $all_fd_token_map = "all_tunnel_online_map";

? ? public function __construct()

{

/* 讀取站點配置 */

? ? ? ? $this->set_config();

? ? ? ? echo "構造函數初始化。。。\n";

//? ? ? ? var_dump(config("database"));

? ? ? ? $this->db_config= config("database");

? ? ? ? //redie 配置

? ? ? ? $this->redis_server= !empty(config("PUBLIC_REDIS_ADDR"))? config("PUBLIC_REDIS_ADDR"): "127.0.0.1";

? ? ? ? $this->redis_port= !empty(config("PUBLIC_REDIS_PORT"))? config("PUBLIC_REDIS_PORT"): "6379";

? ? ? ? $this->redis_pwd= !empty(config("PUBLIC_REDIS_PWD"))? config("PUBLIC_REDIS_PWD"): "";

? ? ? ? $this->clean_all_tunnel_key();

? ? ? ? //swoole

? ? ? ? $this->serv= new \swoole_server("0.0.0.0", $this->port);

? ? ? ? $this->serv->set(array(

'worker_num' => 8,//建議開啟的worker進程數為cpu核數的1-4倍

? ? ? ? ? ? 'daemonize' => false,

? ? ? ? ? ? 'max_request' => 10000,

? ? ? ? ? ? 'dispatch_mode' => 2,

? ? ? ? ? ? 'debug_mode' => 1,

? ? ? ? ? ? 'task_worker_num' => 8

? ? ? ? ));

//'reactor_num' => 8 //,默認會啟用CPU核數相同的數量, 一般設置為CPU核數的1-4倍,最大不得超過CPU核數*4。

? ? ? ? $this->serv->on('Start', array($this, 'onStart'));

? ? ? ? $this->serv->on('Connect', array($this, 'onConnect'));

? ? ? ? $this->serv->on('Receive', array($this, 'onReceive'));

? ? ? ? $this->serv->on('Close', array($this, 'onClose'));

? ? ? ? $this->serv->on('Task', array($this, 'onTask'));

? ? ? ? // bind callback

? ? ? ? $this->serv->on('Finish', array($this, 'onFinish'));

? ? ? ? $this->serv->start();

? ? ? ? if (!defined('GLOBAL_START')) {

$server = new Server();

? ? ? ? ? ? define('GLOBAL_START', true);

? ? ? ? }

}

public function onStart($serv)

{

echo "Start OK\n";

? ? ? ? echo "確保 onstart 時 所有的 相關都初始化 !重啟后 fd 會重頭再記錄 ,redis 里面的數據 將失準";

? ? ? ? dump(config("PUBLIC_REDIS_ADDR"));

? ? ? ? // 清空已有 的redis 相關業務 可能涵蓋 多平臺

? ? }

public function onConnect($serv, $fd, $from_id)

{

//? ? ? ? $serv->send($fd, "Hello {$fd}!");? // 打招呼

? ? ? ? echo "lingking——fd:----" . $fd;? ? ? // 打印

? ? ? ? echo " ";

? ? ? ? echo "lingking——from_id:----" . $from_id; // 打印work id

? ? }

public function onReceive(\swoole_server$serv, $fd, $from_id, $data)

{

echo "有新消息 來自客戶端 {$fd} Client :{$data}\n";

? ? ? ? if ($this->is_json($data)) {

$data = json_decode($data, true);

? ? ? ? }

$param = array(

'fd' => $fd,

? ? ? ? ? ? 'data' => $data

? ? ? ? );

? ? ? ? // start a task

? ? ? ? $serv->task(json_encode($param));

//? ? ? ? echo "上面已經 交個task? 這里不影響 做其他事 over\n";

? ? }

public function onTask($serv, $task_id, $from_id, $in_data)

{

$backbool = "false";

? ? ? ? //? ? ? ? echo "This Task {$task_id} from Worker {$from_id}\n";

//? ? ? ? echo "Data: {$in_data}\n";

//? ? ? ? var_dump(json_decode($in_data,true));

? ? ? ? $fd = json_decode($in_data, true)['fd'];

? ? ? ? $data = json_decode($in_data, true)['data'];

? ? ? ? if (!isset($data["token"])|| !isset($data["platform"])) {

echo "缺少token或者platform";

? ? ? ? ? ? $serv->send($fd, "缺少token或者platform");? // 這里作為回復客戶端

? ? ? ? ? ? return "fd: {$fd} Task {$task_id}'s result";

? ? ? ? }

//? data 中 有三參數 token platfom? info(內涵 now_mac? set mac)

? ? ? ? dump($this->redis_server);

? ? ? ? $redis = new \Redis();

? ? ? ? $redis->pconnect($this->redis_server, $this->redis_port);

? ? ? ? if (!empty($this->redis_pwd)) {

$redis->auth($this->redis_pwd);

? ? ? ? }

$tokenall = $data["token"];

? ? ? ? $time_length = 3 * 60;

? ? ? ? $bad_token_key = "aur_bad_token_" . $tokenall;

? ? ? ? $check_bool = $this->bad_token_check($bad_token_key);

? ? ? ? if (empty($check_bool)) {

$backbool = "false";

? ? ? ? ? ? $re_mag = $this->send_msg($fd, $backbool);? // 這里作為回復客戶端

? ? ? ? ? ? return "fd: {$fd} 觸發的 Task {$task_id} 的 結果:{$re_mag}\n";

? ? ? ? }

$platform = $data["platform"];

? ? ? ? $token = substr($tokenall, 0, 32);

? ? ? ? $tunnel_id = substr($tokenall, 33);

? ? ? ? //? 一個鍵 兩個囊? 一個放最大數量? 另一個放 fd 對? 用hash? token_all:[fd1:1,fd2:1....max_num:100]

? ? ? ? if ($platform == 4) {// 目前只有極光做了 隧道

? ? ? ? ? ? $out_key = "aur_tunnel_online_" . $tokenall;

? ? ? ? ? ? // 先驗證

? ? ? ? ? ? $have_fd = $redis->hExists($out_key, $fd);

? ? ? ? ? ? if ($have_fd) {

$backbool = "true";

? ? ? ? ? ? ? ? echo "有記錄 {$fd}\n";

? ? ? ? ? ? ? ? $re_mag = $this->send_msg($fd, $backbool);? // 這里作為回復客戶端

? ? ? ? ? ? ? ? return "fd: {$fd} 觸發的 Task {$task_id} 的 結果:{$re_mag}\n";

? ? ? ? ? ? }

echo "該id 沒有記錄 {$fd}\n";

? ? ? ? ? ? //? 沒有在里面 就 要重新搞了

? ? ? ? ? ? $have_max = $redis->hExists($out_key, "max_num");

? ? ? ? ? ? if (!$have_max) {

echo "沒找到最大數 {$out_key}\n";

? ? ? ? ? ? ? ? $tunnel_info = $this->set_max_num($prefix = "aur_", $tunnel_id, $token, $out_key);// 重置下

? ? ? ? ? ? ? ? if (!empty($tunnel_info)) {

$max_num = $tunnel_info["online_max_num"];

? ? ? ? ? ? ? ? ? ? $redis->hSet($out_key, "max_num", $max_num);

? ? ? ? ? ? ? ? ? ? echo "設置后獲取max_num:" . $redis->hGet($out_key, "max_num");

//? ? ? ? ? ? ? ? ? ? $redis->expire($out_key,5*60);// 60s? 從庫里面校驗

? ? ? ? ? ? ? ? }else {// 這里 要 做下阻擋 由于 非法token 一直查詢不到 ,每次過來查庫 對 數據庫造成壓力

//bad_token 入庫

? ? ? ? ? ? ? ? ? ? $redis->set("aur_bad_token_" . $tokenall, NOW_TIME + $time_length);

? ? ? ? ? ? ? ? ? ? $max_num = 0; //這里很重要? 就是 當 token 不對 時? $max_num

? ? ? ? ? ? ? ? }

}else {

$max_num = $redis->hGet($out_key, "max_num");

? ? ? ? ? ? }

$num_now = $redis->hLen($out_key)- 1;// 里面多了一個 鍵max_num

? ? ? ? ? ? echo " {$out_key}最大數:{$max_num},現在數:$num_now\n";

? ? ? ? ? ? if (!empty($max_num)&& $max_num > $num_now) {

// 驗證一個 并且放入 (有就算了)

? ? ? ? ? ? ? ? $new_fd = $redis->hSet($out_key, $fd, $fd);

? ? ? ? ? ? ? ? $map_up = $redis->hSet($this->all_fd_token_map, $fd, $out_key); //? all_tunnel_online_map:[fd1:aurtoken,fd2:inttoken2,fd3:token2]

? ? ? ? ? ? ? ? echo "new_fd {$fd} 入庫 \n";

? ? ? ? ? ? ? ? echo "{$fd}:{$out_key}map 入庫結果:{$map_up}\n";

? ? ? ? ? ? ? ? var_dump($new_fd);

? ? ? ? ? ? ? ? $backbool = "true";

? ? ? ? ? ? }

}else {// 如果有其他的 請在這里 做分支判斷

? ? ? ? }

$redis->close();

? ? ? ? $msg = $this->send_msg($fd, $backbool);? // 這里作為回復客戶端

? ? ? ? return "fd: {$fd} Task {$task_id}'s 結果{$msg}";

? ? }

private function bad_token_check($bad_token_key)

{

$redis = new \Redis();

? ? ? ? $redis->pconnect($this->redis_server, $this->redis_port);

? ? ? ? if (!empty($this->redis_pwd)) {

$redis->auth($this->redis_pwd);

? ? ? ? }

$expire = $redis->get($bad_token_key);

? ? ? ? echo "bad 過期時間是:{$expire}\n";

? ? ? ? if ($expire > NOW_TIME) {//被鎖了

? ? ? ? ? ? echo "{$bad_token_key}這token是個壞小子\n";

? ? ? ? ? ? return false;

? ? ? ? }

return true;

? ? }

/**

* @param string $prefix

* @param $tunnel_id

* @param $token

* @param $out_key

* @return bool|mixed

*/

? ? private function set_max_num($prefix = "aur_", $tunnel_id, $token, $out_key)

{

// 矯正用

? ? ? ? echo "矯正ing....................................數據庫查詢\n";

? ? ? ? $tunnel_info = Db::connect($this->db_config)->table($prefix . "tunnel_user_package")->where(['id' => $tunnel_id])->find();

? ? ? ? if (!$tunnel_info) {

return false;

? ? ? ? }

if (md6($tunnel_id . "lingjiang735" . $tunnel_info["salt"])!= $token) {

return false;

? ? ? ? }

return $tunnel_info;

? ? }

public function send_msg($fd, $msg)

{

$reminder = "向->{$fd} 發送-> {$msg}\n";

? ? ? ? $this->serv->send($fd, $msg);

? ? ? ? return $reminder;

? ? }

public function onFinish($serv, $task_id, $data)

{

echo "Task {$task_id} over\n";

? ? ? ? echo "Finish: {$data}\n";

? ? }

public function onClose($serv, $fd, $from_id)

{

echo "1 Client {$fd} close connection\n";

? ? ? ? //? 這個端的唯一 鏈接 id

? ? ? ? $redis = new \Redis();

? ? ? ? $redis->pconnect($this->redis_server, $this->redis_port);

? ? ? ? if (!empty($this->redis_pwd)) {

$redis->auth($this->redis_pwd);

? ? ? ? }

$have_map = $redis->hExists($this->all_fd_token_map, $fd);

? ? ? ? echo "2 {$fd}是否有map?:\n";

? ? ? ? if ($have_map) {

$token_key = $redis->hGet($this->all_fd_token_map, $fd);

? ? ? ? ? ? echo "3 {$fd}查詢到token_key:{$token_key}\n";

? ? ? ? ? ? //刪除該token_key 下的

? ? ? ? ? ? $re = $redis->hDel($token_key, $fd);

? ? ? ? ? ? echo "4 {$fd}刪除結果:$re\n";

? ? ? ? ? ? echo "over\n";

? ? ? ? }else {

echo "3 {$fd}沒有查詢到token_key\n";

? ? ? ? }

$redis->close();

? ? }

private function is_json($str)

{

return is_array(json_decode($str, true))&& !empty(json_decode($str));

? ? }

/**

* 從數據庫拿到

*/

? ? private function set_config()

{

$m = Db::connect($this->db_config)->table('wt_config');

? ? ? ? $r = $m->select();

? ? ? ? foreach ($r as $k => $v) {

$r[$k]['name']= strtoupper($r[$k]['code']);

? ? ? ? }

$r = array_column($r, 'value', 'code');

? ? ? ? cache('config_cache', $r);

? ? ? ? //取配置,賦值

? ? ? ? config(cache('config_cache')); //添加配置

? ? ? ? echo "設置緩存";

? ? }

private function clean_all_tunnel_key()

{

$redis = new \Redis();

? ? ? ? $redisserver = $this->redis_server;

? ? ? ? $redisport = $this->redis_port;

? ? ? ? $redispwd = $this->redis_pwd;

? ? ? ? $redis->pconnect($redisserver, $redisport);

? ? ? ? if (!empty($redispwd)) {

$redis->auth($redispwd);

? ? ? ? }

echo "清理前各個token_list :\n";

? ? ? ? $infos = $redis->keys('aur_tunnel_online_*');

? ? ? ? dump($infos);

? ? ? ? $redis->delete($infos);

? ? ? ? echo "清理前各個token_list :\n";

? ? ? ? $infos = $redis->keys('aur_tunnel_online_*');

? ? ? ? dump($infos);

? ? ? ? echo "清理前map:\n";

? ? ? ? $infos = $redis->keys($this->all_fd_token_map);

? ? ? ? dump($infos);

? ? ? ? $redis->delete($infos);

? ? ? ? echo "清理前各個token_list and map:\n";

? ? ? ? $infos = $redis->keys($this->all_fd_token_map);

? ? ? ? dump($infos);

? ? }

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,868評論 18 139
  • 基于上一篇文章swoole+tp5異步多線程,發現很多問題,所以深入理解一下swoole的進程模型 想探討一下sw...
    會寫bug的鳥閱讀 1,591評論 2 4
  • 文/吉祥君 每個月,總有那么幾天,腦子里像被灌了漿糊,怎么也提不起轉速。碰到這種時候,不管是閱讀還是寫作,就都變得...
    吉祥君閱讀 306評論 0 2
  • 如果你是金子,你要提高你的含金量到一定程度,才會成為發光的金子。當你被挖掘出來,你要經過很痛苦的碾磨、沖刷、浸泡,...
    winifred_閱讀 112評論 0 0
  • 待我老去,老在了日子里,你是否還在,在我的日子里。
    腳大大閱讀 176評論 1 1