主要用于代理MySQL连接,用Navicat Premium直接连接数据库,用不了一会在卡住,用了这个代理就可以流畅使用,也可以用于访问内部数据库或者服务等等。
项目仓库:https://gitee.com/windthesky/forward_proxy.git
配置全部在start.php文件中
<?php/** @noinspection PhpUnused *//** @noinspection PhpUndefinedFieldInspection *//** @noinspection PhpObjectFieldsAreOnlyWrittenInspection */ini_set('memory_limit', '512M');use Workerman\Connection\AsyncTcpConnection;use Workerman\Worker;use Workerman\Connection\TcpConnection;// 自动加载类require_once __DIR__ . '/vendor/autoload.php';require_once __DIR__ . '/common.php';// 是否写入日记const LOG_WRITE = true;// 是否显示日记const SHOW_LOG = true;// 是否超时关闭const TIMEOUT_CLOSE = true;// 超过300秒后发送消息会先断开const TIME = 300;//接收缓冲区大小,默认2M,根据网速和传输数据大小填写,影响最终转发的网速TcpConnection::$defaultMaxSendBufferSize = 2*1024*1024;AsyncTcpConnection::$defaultMaxSendBufferSize = 2*1024*1024;$proxy_list = [ [ 'type' => 'tcp', 'host' => '127.0.0.1', 'port' => 3306, 'local_port' => 33060, ],];$app_list = [];$connect_list = [];$client_list = [];/** * app收到 * @param AsyncTcpConnection $app_connection * @param $data * @return void */function app_message(AsyncTcpConnection $app_connection,$data): void{ try { write_log('app收到:开始'); $client_id=$app_connection->client_id; global $connect_list; write_log(['app收到:',$data]); write_log(['app收到-client_id:',$client_id]); $connect_list[$client_id]->send($data); write_log('app收到-处理完:'); } catch (Throwable $e) { write_log(['app收到:异常==》',$e->getMessage()]); $app_connection->close(); }}/** * app错误 * @param AsyncTcpConnection $app_connection * @return void */function app_error(AsyncTcpConnection $app_connection): void{ try { write_log('app错误:'); $client_id=$app_connection->client_id; global $connect_list; $connect_list[$client_id]->close(); write_log('app错误:执行完'); } catch (Throwable $e) { write_log(['app错误:异常==》',$e->getMessage()]); }}/** * app关闭 * @param AsyncTcpConnection $app_connection * @return void */function app_close(AsyncTcpConnection $app_connection): void{ try { write_log('app关闭:'); $client_id=$app_connection->client_id; global $connect_list,$app_list; $connect_list[$client_id]->close(); unset($app_list[$client_id]); write_log('app关闭:执行完'); } catch (Throwable $e) { write_log(['app关闭:异常==》',$e->getMessage()]); }}//Todo 客户端连接处理/** * 客户端连接处理 * @param TcpConnection $connection * @return void */function handle_connection(TcpConnection $connection): void{ try { write_log('客户端连接:'); $connection->lastMessageTime = time(); global $app_list,$connect_list; $client_id = 'client-'.session_create_id(); $connection->client_id = $client_id; $connect_list[$client_id]=$connection; $proxy_url=$connection->worker->proxy_url; write_log(['客户端连接:开始==》',$connection->client_id]); $app_list[$client_id] = new AsyncTcpConnection($proxy_url); $app_list[$client_id]->client_id = $client_id; $app_list[$client_id]->onMessage = 'app_message'; $app_list[$client_id]->onError = 'app_error'; $app_list[$client_id]->onClose = 'app_close'; $app_list[$client_id]->connect(); write_log(['客户端连接:完成==》',$connection->client_id]); } catch (Throwable $e) { write_log(['客户端连接:异常==》',$connection->client_id,$e->getMessage()]); }}/** * 收到消息处理 * @param TcpConnection $connection * @param $data * @return void */function handle_message(TcpConnection $connection,$data): void{ try { write_log(['收到消息:',$data]); global $app_list; if(TIMEOUT_CLOSE && time()-$connection->lastMessageTime>TIME){ write_log(['收到消息:超时关闭']); $connection->close(); return; } $app_list[$connection->client_id]->send($data); $connection->lastMessageTime = time(); write_log(['收到消息:完']); } catch (Throwable $e) { write_log(['收到消息:异常==》',$connection->client_id,$e->getMessage()]); }}/** * 处理错误 * @param TcpConnection $connection * @return void */function handle_error(TcpConnection $connection): void{ try { write_log(['处理错误:开始==》',$connection->client_id]); $client_id=$connection->client_id; global $app_list; if (empty($app_list[$client_id])) return; $app_list[$client_id]->close(); write_log(['处理错误:完成==》',$client_id]); } catch (Throwable $e) { write_log(['处理错误:异常==》',$e->getMessage()]); }}/** * 处理关闭 * @param TcpConnection $connection * @return void */function handle_close(TcpConnection $connection): void{ try { write_log(['处理关闭:开始==》',$connection->client_id]); $client_id=$connection->client_id; global $app_list,$connect_list; if (empty($app_list[$client_id])) return; $app_list[$client_id]->close(); unset($connect_list[$client_id]); write_log(['处理关闭:完成==》',$client_id]); } catch (Throwable $e) { write_log(['处理关闭:异常==》',$e->getMessage()]); }}$worker = new Worker();$worker->onWorkerStart = function() { global $client_list,$proxy_list; foreach($proxy_list as $k=>$v) { $url=$v['type'].'://0.0.0.0:'.$v['local_port']; $proxy_url=$v['type'].'://'.$v['host'].':'.$v['port']; echo '监听地址:'.$url.PHP_EOL; echo '代理地址:'.$proxy_url.PHP_EOL; $client_list[$k] = new Worker($url); $client_list[$k]->proxy_key = $k; $client_list[$k]->proxy_info = $v; $client_list[$k]->proxy_url = $proxy_url; $client_list[$k]->onConnect = 'handle_connection'; $client_list[$k]->onMessage = 'handle_message'; $client_list[$k]->onError = 'handle_error'; $client_list[$k]->onClose = 'handle_close'; $client_list[$k]->listen(); }};Worker::runAll();启动以debug(调试)方式启动
php start.php start以daemon(守护进程)方式启动
php start.php start -d停止
php start.php stop重启
php start.php restart平滑重启
php start.php reload查看状态
php start.php statusWindows 启动双击start_for_win.bat