简介:
在CentOS上安装Swoole,Swoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务,让 PHP 不再局限于 Web 领域。
安装环境及版本:
系统环境:CentOS Linux release 7.5.1804 (Core)
Swoole版本:v2.0.6.tar.gz
一、前提条件
已经安装了PHP
二、安装
下载:wget https://github.com/swoole/swoole-src/archive/v2.0.6.tar.gz
解压缩:tar zxvf swoole-src-2.0.6.tar.gz
[root@localhost ~]# ll
total 652
-rw-------. 1 root root 1291 Apr 23 2019 anaconda-ks.cfg
drwxrwxr-x. 11 root root 4096 Jan 26 2017 swoole-src-2.0.6
-rw-r--r--. 1 root root 658124 Jun 30 04:41 swoole-src-2.0.6.tar.gz
进入解压缩目录:
[root@localhost ~]# cd swoole-src-2.0.6
[root@localhost swoole-src-2.0.6]# ll
total 1072
drwxrwxr-x. 2 root root 4096 Jan 26 2017 benchmark
-rw-rw-r--. 1 root root 1844 Jan 26 2017 CMakeLists.txt
-rwxrwxr-x. 1 root root 12656 Jan 26 2017 config.m4
-rw-rw-r--. 1 root root 62 Jan 26 2017 CREDITS
drwxrwxr-x. 31 root root 4096 Jan 26 2017 examples
drwxrwxr-x. 3 root root 4096 Jan 26 2017 include
-rw-rw-r--. 1 root root 11362 Jan 26 2017 LICENSE
-rw-rw-r--. 1 root root 12367 Jan 26 2017 package.xml
-rwxrwxr-x. 1 root root 15791 Jan 26 2017 php7_wrapper.h
-rwxrwxr-x. 1 root root 16850 Jan 26 2017 php_swoole.h
drwxrwxr-x. 5 root root 128 Jan 26 2017 php-tests
-rw-rw-r--. 1 root root 13936 Jan 26 2017 README.md
drwxrwxr-x. 11 root root 127 Jan 26 2017 src
-rw-rw-r--. 1 root root 22431 Jan 26 2017 swoole_async.c
-rw-rw-r--. 1 root root 4821 Jan 26 2017 swoole_atomic.c
-rw-rw-r--. 1 root root 11163 Jan 26 2017 swoole_buffer.c
-rwxrwxr-x. 1 root root 39517 Jan 26 2017 swoole.c
-rw-rw-r--. 1 root root 4170 Jan 26 2017 swoole_channel.c
-rw-rw-r--. 1 root root 61255 Jan 26 2017 swoole_client.c
-rwxrwxr-x. 1 root root 35036 Jan 26 2017 swoole_client_coro.c
-rwxrwxr-x. 1 root root 10175 Jan 26 2017 swoole_config.h
-rwxrwxr-x. 1 root root 18642 Jan 26 2017 swoole_coroutine.c
-rwxrwxr-x. 1 root root 5378 Jan 26 2017 swoole_coroutine.h
-rw-rw-r--. 1 root root 10823 Jan 26 2017 swoole_coroutine_util.c
-rw-rw-r--. 1 root root 17296 Jan 26 2017 swoole_event.c
-rw-rw-r--. 1 root root 57668 Jan 26 2017 swoole_http_client.c
-rwxrwxr-x. 1 root root 41975 Jan 26 2017 swoole_http_client_coro.c
-rw-rw-r--. 1 root root 4772 Jan 26 2017 swoole_http_client.h
-rw-rw-r--. 1 root root 5281 Jan 26 2017 swoole_http.h
-rwxrwxr-x. 1 root root 70391 Jan 26 2017 swoole_http_server.c
-rw-rw-r--. 1 root root 20174 Jan 26 2017 swoole_http_v2_server.c
-rw-rw-r--. 1 root root 6131 Jan 26 2017 swoole_lock.c
-rw-rw-r--. 1 root root 6205 Jan 26 2017 swoole_mmap.c
-rw-rw-r--. 1 root root 7494 Jan 26 2017 swoole_module.c
-rw-rw-r--. 1 root root 44863 Jan 26 2017 swoole_mysql.c
-rwxrwxr-x. 1 root root 29502 Jan 26 2017 swoole_mysql_coro.c
-rw-rw-r--. 1 root root 23317 Jan 26 2017 swoole_mysql.h
-rw-rw-r--. 1 root root 29715 Jan 26 2017 swoole_process.c
-rw-rw-r--. 1 root root 24455 Jan 26 2017 swoole_redis.c
-rwxrwxr-x. 1 root root 121635 Jan 26 2017 swoole_redis_coro.c
-rw-rw-r--. 1 root root 14771 Jan 26 2017 swoole_redis_server.c
-rwxrwxr-x. 1 root root 89376 Jan 26 2017 swoole_server.c
-rw-rw-r--. 1 root root 17786 Jan 26 2017 swoole_server_port.c
-rw-rw-r--. 1 root root 18594 Jan 26 2017 swoole_table.c
-rwxrwxr-x. 1 root root 12030 Jan 26 2017 swoole_timer.c
-rw-rw-r--. 1 root root 18986 Jan 26 2017 swoole_websocket_server.c
drwxrwxr-x. 4 root root 239 Jan 26 2017 tests
drwxrwxr-x. 4 root root 138 Jan 26 2017 thirdparty
drwxrwxr-x. 2 root root 20 Jan 26 2017 tools
drwxrwxr-x. 2 root root 24 Jan 26 2017 travis
-rw-rw-r--. 1 root root 4575 Jan 26 2017 Version2.md
找到phpize位置,并运行生成configure模块:/usr/bin/phpize
[root@localhost swoole-src-2.0.6]# whereis phpize
phpize: /usr/bin/phpize /usr/share/man/man1/phpize.1.gz
[root@localhost swoole-src-2.0.6]# /usr/bin/phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303
安装插件:yum -y install gcc-c++
检测:./configure –with-php-config=/usr/bin/php-config
[root@localhost swoole-src-2.0.6]# ./configure --with-php-config=/usr/bin/php-config
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
......
checking whether to build static libraries... no
configure: creating ./config.status
config.status: creating config.h
config.status: executing libtool commands
安装:make && make install
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,-rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/lib64/php/modules/
在PHP中增加swoole模块,新建:vi /etc/php.d/swoole.ini,并添加extensionon=swoole.so
[root@localhost swoole-src-2.0.6]# cat /etc/php.d/swoole.ini
extensionon=swoole.so
三、验证
重启:
[root@localhost swoole-src-2.0.6]# systemctl restart php-fpm
[root@localhost swoole-src-2.0.6]# systemctl restart httpd
查询php 中的扩展:php -m,如果有swoole,说明安装成功
[root@localhost swoole-src-2.0.6]# php -m
[PHP Modules]
bz2
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
json
libxml
mbstring
mysqli
mysqlnd
openssl
pcntl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
Reflection
session
shmop
SimpleXML
sockets
SPL
sqlite3
standard
swoole
sysvmsg
sysvsem
sysvshm
tokenizer
wddx
xml
xmlreader
xmlwriter
xsl
Zend OPcache
zip
zlib
[Zend Modules]
Zend OPcache
四、使用
4.1 服务端
新建类:多进程接受消息,根据消息类型做相应处理
SwooleUDPServer::getIntance()->exec();
class SwooleUDPServer{
private $serv;
private static $singleinstance=false;
public static function getIntance(){
if(self::$singleinstance==false){
self::$singleinstance=new self;
}
return self::$singleinstance;
}
function __construct(){
LogInfo::log("SwooleUDPServer::__construct");
}
public function exec(){
LogInfo::log("SwooleUDPServer::exec");
try {
//Base模式(SWOOLE_BASE)传统的异步非阻塞Server,reactor和worker是同一个角色。TCP连接是在worker进程中维持的。如果客户端连接之间不需要交互,可以使用BASE模式。如Memcache、Http服务器等。
//线程模式多线程Worker模式,Reactor线程来处理网络事件轮询,读取数据。得到的请求交给Worker线程去处理。缺点:一个线程发生内存错误,整个进程会全部结束。由于PHP的ZendVM在多线程模式存在内存错误,多线程模式在v1.6.0版本后已关闭。
//进程模式与多线程Worker模式不同的是,线程换成了进程。Reactor线程来处理网络事件轮询,读取数据。得到的请求交给Worker进程去处理。适合业务逻辑非常复杂的场景。如WebSocket服务器等
$this->serv = new swoole_server(Config::tcp_server, Config::tcp_port, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
//Client主动Connect的时候,Client实际上是与Master进程中的某个Reactor线程发生了连接。
//当TCP的三次握手成功了以后,由这个Reactor线程将连接成功的消息告诉Manager进程,再由Manager进程转交给Worker进程。
//在这个Worker进程中触发了OnConnect的方法。
//当Client向Server发送了一个数据包的时候,首先收到数据包的是Reactor线程,同时Reactor线程会完成组包,再将组好的包交给Manager进程,由Manager进程转交给Worker。
//此时Worker进程触发OnReceive事件。
//如果在Worker进程中做了什么处理,然后再用Send方法将数据发回给客户端时,数据则会沿着这个路径逆流而上。
$this->serv->set([
'worker_num' => 4, # 4个worker
'task_worker_num' => 8, # 4个task
'deamonize' => false,
'max_request' => 10000,//参数表示worker进程在处理完n次请求后结束运行。manager会重新创建一个worker进程。此选项用来防止worker进程内存溢出
]);
//启动Server后,客户端无需Connect,直接可以向Server监听的端口发送数据包。
$this->serv->on('Packet', array($this, 'onPacket'));
$this->serv->on('Task', array($this, 'onTask'));
$this->serv->on('Finish', array($this, 'onFinish'));
$this->serv->start();
} catch (Exception $e) {
LogInfo::log($e->getMessage());
}
}
public function onPacket(swoole_server $serv, $data, $clientInfo ) {
try{
$serv->task($clientInfo['address'] . ',' . $clientInfo['port'] . ',' . $data);
} catch (Exception $e) {
LogInfo::log($e->getMessage());
}
}
public function onTask(swoole_server $serv, $task_id, $from_id, $data) {
//echo "This Task {$task_id} from Worker {$from_id}\n";
echo date("Y-m-d H:i:s",time()) . " recv data {$data}\n";
try{
$ip = explode(',', $data)[0];
$port = explode(',', $data)[1];
$msg = explode(',', $data)[2];
$msgtype = substr($msg, 0,1);
switch ($msgtype){
default:
break;
}
} catch (Exception $e) {
LogInfo::log($e->getMessage());
}
}
public function onFinish(swoole_server $serv,$task_id, $data) {
}
}
4.2 客户端
新建类,发消息
SwooleUDPClientPC::getIntance()->send("401010101960");
class SwooleUDPClientPC{
private static $singleinstance=false;
public static function getIntance(){
if(self::$singleinstance==false){
self::$singleinstance=new self;
}
return self::$singleinstance;
}
function __construct(){
LogInfo::log("SwooleUDPClient::__construct");
}
public function send($data){
//char ucCmd; //’4’设置工作压力
//char aucSetStr[3]; //数值的16进制字符串,数值见表7, 16进制字符串(000~960)
// char ucCmd; // ‘5’运行;‘6’停止;‘7’长按运行
$client = false;
try{
$client = new swoole_client(SWOOLE_SOCK_UDP);
if (!$client->connect(Config::tcp_server, Config::tcp_port)){
echo "connect: " . $swoole_client->errCode . "\n";
return;
}
echo date("Y-m-d H:i:s",time()) . ' ' . "send: " . $data . "\n";
if(!$client->send($data)){
echo "send: " . $swoole_client->errCode . "\n";
return;
}
} catch (Exception $e) {
LogInfo::log($e->getMessage());
}finally{
if($client){
$client->close();
}
}
}
}