PHP下Swoole安装及使用(CentOS)

简介:

在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();
			}
		}
	}
}

发表回复