proxy_pool.php


<?php class ProxyServer
{
protected $frontends;
protected $backends;
/**
* @var swoole_server
*/
protected $serv;
protected $index = 0;
protected $mode = SWOOLE_BASE;
protected $backendServer; function run($backendServer = array('host' => '127.0.0.1', 'port' => '80'), $port = 9501, $host = '0.0.0.0')
{
$this->backendServer = $backendServer;
$serv = new swoole_server($host, $port, $this->mode);
$serv->set(array(
'worker_num' => 8, //worker process num
//'backlog' => 128, //listen backlog
//'open_tcp_keepalive' => 1,
//'log_file' => '/tmp/swoole.log', //swoole error log
));
$serv->on('WorkerStart', array($this, 'onStart'));
$serv->on('Receive', array($this, 'onReceive'));
$serv->on('Close', array($this, 'onClose'));
$serv->on('WorkerStop', array($this, 'onShutdown'));
$serv->start();
} function onStart($serv)
{
$this->serv = $serv;
//echo "Server: start.Swoole version is [" . SWOOLE_VERSION . "]\n";
} function onShutdown($serv)
{
echo "Server: onShutdown\n";
} function onClose($serv, $fd, $from_id)
{
//清理掉后端连接
if (isset($this->frontends[$fd])) {
$backend_socket = $this->frontends[$fd];
$backend_socket->closing = true;
$backend_socket->close();
unset($this->backends[$backend_socket->sock]);
unset($this->frontends[$fd]);
}
echo "onClose: frontend[$fd]\n";
} function onReceive($serv, $fd, $from_id, $data)
{
//尚未建立连接
if (!isset($this->frontends[$fd])) {
//连接到后台服务器
$socket = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
$socket->closing = false;
$socket->on('connect', function (swoole_client $socket) use ($data) {
$socket->send($data);
});
$socket->on('error', function (swoole_client $socket) use ($fd) {
echo "ERROR: connect to backend server failed\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
});
$socket->on('close', function (swoole_client $socket) use ($fd) {
echo "onClose: backend[{$socket->sock}]\n";
unset($this->backends[$socket->sock]);
unset($this->frontends[$fd]);
if (!$socket->closing) {
$this->serv->close($fd);
}
});
$socket->on('receive', function (swoole_client $socket, $_data) use ($fd) {
$this->serv->send($fd, $_data);
});
if ($socket->connect($this->backendServer['host'], $this->backendServer['port'])) {
$this->backends[$socket->sock] = $fd;
$this->frontends[$fd] = $socket;
} else {
echo "ERROR: cannot connect to backend server.\n";
$this->serv->send($fd, "backend server not connected. please try reconnect.");
$this->serv->close($fd);
}
} //已经有连接,可以直接发送数据
else {
/**
* @var $socket swoole_client
*/
$socket = $this->frontends[$fd];
$socket->send($data);
}
}
}
// config
$backendServerList = [
[
'host' => 'api.eelly.com', 'port' => 443, 'proxy_port' => 9501,
],
]; $workerNum = count($backendServerList);
$pool = new Swoole\Process\Pool($workerNum);
$pool->on("WorkerStart", function ($pool, $workerId) use ($backendServerList) {
echo "Worker#{$workerId} is started\n";
$backendServer = $backendServerList[$workerId];
$serv = new ProxyServer($backendServer, $backendServer['proxy_port']);
echo "Remote {$backendServer['host']}:{$backendServer['port']} -> Local {$backendServer['proxy_port']}\n";
$serv->run();
});
$pool->start();

swoole 连接池的更多相关文章

  1. 用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

  2. Swoole MySQL 连接池的实现

    目录 概述 代码 扩展 小结 概述 这是关于 Swoole 入门学习的第八篇文章:Swoole MySQL 连接池的实现. 第七篇:Swoole RPC 的实现 第六篇:Swoole 整合成一个小框架 ...

  3. 如何在 Swoole 中优雅的实现 MySQL 连接池

    如何在 Swoole 中优雅的实现 MySQL 连接池 一.为什么需要连接池 ? 数据库连接池指的是程序和数据库之间保持一定数量的连接不断开, 并且各个请求的连接可以相互复用, 减少重复连接数据库带来 ...

  4. Swoole Redis 连接池的实现

    概述 这是关于 Swoole 入门学习的第九篇文章:Swoole Redis 连接池的实现. 第八篇:Swoole MySQL 连接池的实现 第七篇:Swoole RPC 的实现 第六篇:Swoole ...

  5. Swoole 实战:MySQL 查询器的实现(协程连接池版)

    目录 需求分析 使用示例 模块设计 UML 类图 入口 事务 连接池 连接 查询器的组装 总结 需求分析 本篇我们将通过 Swoole 实现一个自带连接池的 MySQL 查询器: 支持通过链式调用构造 ...

  6. 转 Swoole】用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

  7. Swoole 中使用 PDO 连接池、Redis 连接池、Mysqli 连接池

    连接池使用说明 所有连接池的实现均基于 ConnectionPool 原始连接池: 连接池的底层原理是基于 Channel 的自动调度: 开发者需要自己保证归还的连接是可重用的: 若连接不可重用,需要 ...

  8. 实现一个协程版mysql连接池

    实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康:基于swoole的chanel. 最近事情忙,心态也有点不积极.技术倒是没有落下,只是越来越不想写博客了.想到 ...

  9. 关于PHP连接池扩展php-cp遇到的那些坑

    php-cp是国内大神写的php第三方扩展,具体就不用多说了,细读https://github.com/swoole/php-cp,下面来说说今天安装方法. 环境:CentOS7.2.1511 由于本 ...

随机推荐

  1. CodeForces - 95B

    Petya loves lucky numbers. Everybody knows that positive integers are lucky if their decimal represe ...

  2. 安全性测试入门 (五):Insecure CAPTCHA 验证码绕过

    本篇继续对于安全性测试话题,结合DVWA进行研习. Insecure Captcha不安全验证码 1. 验证码到底是怎么一回事 这个Captcha狭义而言就是谷歌提供的一种用户验证服务,全称为:Com ...

  3. Mysql 如何设置字段自动获取当前时间,附带添加字段和修改字段的例子

    --添加CreateTime 设置默认时间 CURRENT_TIMESTAMP  ALTER TABLE `table_name`ADD COLUMN  `CreateTime` datetime N ...

  4. java打印堆栈信息

    StackTraceElement[] stackElements = new Throwable().getStackTrace(); if(stackElements != null){ for( ...

  5. qrcode.js的识别解析二维码图片和生成二维码图片

    qrcode只通过前端就能生成二维码和解析二维码图片, 首先要引入文件qrcode.js,下载地址为:http://static.runoob.com/download/qrcodejs-04f46c ...

  6. uvm_sqr_ifs——TLM1事务级建模方法(四)

    与uvm_tlm_if_base 一样,这个类也没有派生自任何类,定义了如下几个接口:get_next_item, try_next_item, item_done, get, peek, put, ...

  7. newsyslog.conf详解

    newsyslog.conf 指出了哪个日志文件要被管理,要保留多少和它们什么时候被创建.日志文件可以在它们达到一定大小或者在特定的日期被重新整理.# configuration file for n ...

  8. C++编写双向链表

    创建双向链表类,该类有默认构造函数.类的拷贝函数.类的.实现链表添加数据.升序排序.查找链表中某个节点及删除链表中某个节点的操作 代码实现: #include<iostream> #inc ...

  9. C++,C++编程,Windows编程,MFC

    编程 我们日常生活中接触到的电子类产品中的应用都是由编程而来 为什么编程,偷懒 我们通过编程驱使(指挥,命令)的是电信号 为什么上面说编程是偷懒,电的发现,给人们带来了便利,人们在各个方面驱使(换成“ ...

  10. getline()读入一整行

    string line; getline(cin, line); cin不能读入空行,用getline可以读入空行.