Swoole的基本语法

linux的基础命令:

        1.netstat -anp|grep 9501 查看9051端口;

        2.telnet 127.0.0.1 9501                              监听9501端口;

        3.kill -9 XXX                                              强制杀死进程;

一、swoole_server

server(服务端):

<?php 
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new \swoole_server("127.0.0.1", 9501); 

$serv->set([
	'worker_num' => 4,    //进程数 是cpu的1-4倍
]);
/*
*	$fd 		客户端连接的唯一标识
*	$reactor_id 	线程id
*/
//监听连接进入事件
$serv->on('connect', function ($serv, $fd,$reactor_id) {  
    echo "Client:{$reactor_id}--{$fd} Connect.\n";
});

//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    $serv->send($fd, "Server:{$reactor_id}--{$fd} ".$data);
});

//监听连接关闭事件
$serv->on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});

//启动服务器
$serv->start();
 ?>

 

client(客户端):

<?php
//连接swoole 服务
$cli = new swoole_client(SWOOLE_TCP);

//判断连接状态(同步连接模式)
if ($cli->connect('127.0.0.1', 9501)) {
      echo "成功";
} else {
      echo "失败";
}

//写入CLI提示信息,
fwrite(STDOUT, '请输入你得名字:');

//获取用户输入数据  
$name = trim(fgets(STDIN));

//发送消息给server
$cli->send($name);

//接收来自server的消息
$rel=$cli->recv();
echo $rel;


二、Hppt_swoole

server:

<?php
//连接一个新的服务 0.0.0.0是监听所有的服务
$cli=new swoole_http_server("0.0.0.0",9501);

$cli->on('request',function($request,$response){
	//使用write分段发送数据后,end方法将不接受任何参数
	$response->write(json_encode($request->get));
	//发送Http响应体,并结束请求处理。
	$response->end('ssss'.json_encode($request->get));
});
//启动
$cli->start();

?>

结果:

    访问http://127.0.0.1:9501?name=1,html输出是{"name":"111111"},而非ssss.{"name":"111111"};

 

server中的set:

//连接设置
$cli->set([
	//类似于重定向
	'enable_static_handler'=>true,
	'docment_root'=>"/www/wwwroot/laravel/public/swoole/data",
]);

 

三、Web_socket

    1.web_socket面向过程的写法:

 

<?php
//创建websocket服务器对象,监听0.0.0.0:9501端口
$server = new swoole_websocket_server("0.0.0.0", 9501);

//监听WebSocket连接打开事件
$server->on('open', function ($server, $request) {
	//push是往前端传递的方法
	$server->push($request->fd,'小子,你连接成功了');
	//所有输出的命令是直接输出于终端
    // var_dump("你已经开启服务:{$request->fd}\n");
});

//监听WebSocket消息事件
$server->on('message', function ($server, $frame) {
    // var_dump("新的消息:{$frame->data}\n");
    $server->push($frame->fd, "{$frame->data}");
});

//监听WebSocket连接关闭事件
$server->on('close', function ($ser, $fd) {
	// $server->push($fd,'我睡呀,你玩吧!');
    var_dump("你好,我的{$fd}\n");
});

$server->start();

 

    2.web_socket面向对象的写法:

 

<?php

/**
*	 socket面向对象的编译
*
*/
class Ws
{
	CONST HOST='0.0.0.0';
	CONST PORT='9501';
	public $ws=null;

	function __construct()
	{
		$this->ws=new swoole_websocket_server(self::HOST,self::PORT);
		$this->ws->on('open',[$this,'onopen']);
		$this->ws->on('message',[$this,'onmessage']);
		$this->ws->on('close',[$this,'onclose']);
		$this->ws->start();
	}

	/**
		监听开启事件的回调
	*/
	function onopen($server, $request)
	{
		$server->push($request->fd,'小子,面向对象你也连接成功了');
	}
	
	/**
		监听接收事件的回调
	*/
	function onmessage($server, $frame)
	{
		$server->push($frame->fd, "{$frame->data}");
	}
	/**
		监听关闭事件的回调
	*/
	function onclose($ser, $fd)
	{
		var_dump("你好,我的{$fd}\n");
	}
}

$new=new Ws();

 

    web_sockethtml的写法:

 

<!DOCTYPE html>
<html>
<head>
	<title>我是来测试的</title>
</head>
<body>
<h1>我是来测试的11111111111</h1>
<script type="text/javascript">
	//连接服务
	var wsServer = 'ws://140.82.0.240:9501';
	//实例化
	var websocket = new WebSocket(wsServer);

	//监听开启事件(只负责监听,没有实际的开启作用)
	websocket.onopen = function (evt) {
		websocket.send('我是来搞事的!!!');
	    // console.log("连接成功html");
	};
	//消息
	websocket.onmessage = function (evt) {
		//监听消息后,直接给服务器传递消息
	    console.log('来自server的最新消息: ' + evt.data);
	};
	//关闭事件
	websocket.onclose = function (evt) {
		console.log("我关闭了html");
	};
	//报错
	websocket.onerror = function (evt, e) {
	    console.log('Error occured: ' + evt.data);
	};
</script>
</body>
</html>

3.task

 使用场景

  • 执行耗时的操作(发送邮件 广播等)

    注意:

  • 投递异步任务之后程序会继续往下执行,不会等待任务执行完后再继续向下执行
<?php

/**
*	 socket面向对象的编译
*
*/
class Ws
{
	CONST HOST='0.0.0.0';
	CONST PORT='9501';
	public $ws=null;

	function __construct()
	{
		$this->ws=new swoole_websocket_server(self::HOST,self::PORT);
		$this->ws->set([
			//启动task必须要设置其数量
			'task_worker_num'=>2,
		]);
		$this->ws->on('open',[$this,'onopen']);
		$this->ws->on('message',[$this,'onmessage']);
		$this->ws->on('task',[$this,'onTask']);
		$this->ws->on('finish',[$this,'onFinish']);
		$this->ws->on('close',[$this,'onclose']);
		$this->ws->start();
	}

	/**
		监听开启事件的回调
	*/
	function onopen($server, $request)
	{
		$server->push($request->fd,'小子,面向对象你也连接成功了');
	}
	
	/**
		监听接收事件的回调
	*/
	function onmessage($server, $frame)
	{
		//投递异步任务task,非阻塞,使用必须设置Server的onTask和onFinish事件回调函数
		$data=[
			'name'=>'你大爷的',
			'id'=>$frame->fd,
		];
		$server->task($data);
		$server->push($frame->fd, "{$frame->data}");
	}
	/**
		监听关闭事件的回调
	*/
	function onclose($ser, $fd)
	{
		print_r("你好,我的{$fd}\n");
	}

	/**
	*	$serv 			服务
	*	$task_id		任务ID,由swoole扩展内自动生成,用于区分不同的任务
	*	$src_worker_id 	$task_id和$src_worker_id组合起来才是全局唯一的,不同的worker进程投递的任务ID可能会有相同
	*	$data 			是任务的内容
	*/
	function onTask($serv,$task_id,$src_worker_id,$data)
	{
		//在终端输出
		print_r($data).'/n';
		//执行耗时任务
		sleep(10);
		//回调于onFinish
		return '你二大爷的';
	}
	/**
	*	$task_id 		是任务的ID
	*	$data			是任务处理的结果内容
	*/
	function onFinish($serv,$task_id,$data)
	{
		print_r($data).'/n';
	}

}

$new=new Ws();

    html测试结果:

    CLI返回结果:

 

四、异步IO

    1.毫秒定时器

/**
		监听接收事件的回调
	*/
	function onmessage($server, $frame)
	{
		//投递异步任务task,非阻塞,使用必须设置Server的onTask和onFinish事件回调函数
		$data=[
			'name'=>'你大爷的',
			'id'=>$frame->fd,
		];
		$server->task($data);
		//异步毫秒定时器
		//每3秒循环执行
		swoole_timer_tick(3000,function() use($server, $frame){
			$server->push($frame->fd, "我是循环的");
		});

		//3秒后执行一次
		swoole_timer_after(3000,function() use($server, $frame){
			$server->push($frame->fd, "我就只有一次");
		});

		$server->push($frame->fd, "{$frame->data}");
	}

    执行结果:

    

    2.异步读取文件

<?php 

/**
*	异步读取文件
*	__DIR__		当前文件的路径(php魔术方法)
*	PHP_EOL		不同系统对应不同的换行符
*/
$res=swoole_async_readfile(__DIR__.'/1.txt', function($filename,$fileContent){
	echo 'name:'.$filename.PHP_EOL;
	echo 'content:'.$fileContent.PHP_EOL;
});

var_dump($res);

echo 123;

    执行结果:先执行同步,后执行异步

 


    3.1异步写入文件

<?php 
/**
*	异步写入
*/
$content='你大爷的,现在几点了?'.date('H:i:s').PHP_EOL;

swoole_async_writefile(__DIR__.'/1.log',$content,function($filename){
	echo '写入成功!'.PHP_EOL;
},FILE_APPEND);

echo '我是123'.PHP_EOL;

     执行结果:先执行同步,后执行异步

    3.2异步写入html信息

/**
*	异步获取url信息并写入
*
*/
//连接一个新的服务 0.0.0.0是监听所有的服务
$cli=new swoole_http_server("0.0.0.0",9501);

$cli->on('request',function($request,$response){
	$content=[
		'time:'=>date('H:i:s'),
		'get:'=>$request->get,
		'post:'=>$request->post,
		'header:'=>$request->header,
	];
	swoole_async_writefile(__DIR__.'/access.log',json_encode($content).PHP_EOL,function($filename){
		echo '写入成功!'.PHP_EOL;
	},FILE_APPEND);

	$response->end('ssss'.json_encode($request->get));

});

//启动
$cli->start();

结果:

    访问http://127.0.0.1:9501?name=1,html输出是ssss{"name":"111111"}生成了access.log文件;

 

    4.异步操作mysql

<?php 
/**
* 	异步sql的操作 
*/
class Mysql
{
	public $sql=null;
	public $config=null;
	function __construct()
	{
		//实例化一个数据库的连接
		$this->sql= new swoole_mysql;
		//配置信息
		$this->config=[
			'host' => '140.82.0.240',
		    'port' => 3306,
		    'user' => 'weibao',
		    'password' => 'aCHZhsKTzrZpR',
		    'database' => 'weibao',
		    'charset' => 'utf8', //指定字符集
		    'timeout' => 2,  // 可选:连接超时时间(非查询超时时间),默认为SW_MYSQL_CONNECT_TIMEOUT(1.0)
		];
	}
	public function select($id,$table)
	{
		//连接数据库
		$this->sql->connect($this->config,function($db,$result) use($id,$table){
			//连接失败,打印错误信息
			if ($result == false) {
				echo '连接失败'.PHP_EOL;
				echo $db->connect_errno.PHP_EOL;
				echo $db->connect_error.PHP_EOL;
				die;
			}
			//编写sql
			$sql='select * from hy_'.$table.' where '.$table.'_id =' .$id;
			// echo $sql.PHP_EOL;
			//执行sql语句
			/**
			*	执行失败,$result为false,读取$link对象的error属性获得错误信息,errno属性获得错误码
			*	执行成功,SQL为非查询语句,$result为true,读取$link对象的affected_rows属性获得影响的行数,insert_id属性获得Insert操作的自增ID
			*	执行成功,SQL为查询语句,$result为结果数组
			*/
			$db->query($sql,function($link,$result){
				if ($result === false) {
					echo $link->error.PHP_EOL;
				}elseif ($result === true) {
					echo '成功了!'.PHP_EOL;
				}else{
					print_r($result).PHP_EOL;
				}
				//$link就是$db
				// print_r($link);
				//关闭连接
				$link->close();
			});
		});
		return true;
	}

}

$res=new Mysql();
$select=$res->select(1,'ads');
var_dump($select).PHP_EOL;
echo "start".PHP_EOL;

    执行结果:先执行同步,后执行异步

    5.异步redis

 

swoole使用redis的前置条件

  • redis服务
  • hiredis
  • 编译swoole需要加入 -enable-async-redis

    编译安装hiredis

使用 Redis客户端,需要安装 hiredis库,下载 hiredis源码后,执行
make -j
sudo make install
sudo ldconfig

    hiredis下载地址

    启用异步Redis客户端

编译 swoole时,在 configure指令中加入 --enable-async-redis
[root@izwz93ee3z8wdxsujiec2oz swoole]# ./configure --with-php-config=/usr/local/php/bin/php-config --enable-async-redis
make clean
make -j
sudo make install

    查看PHPswoole扩展:php -m 
    查看hiredis是否编译安装成功:php --ri swoole

    代码测试

<?php 
//实例化
$redisClient = new Swoole\Redis;// Swoole\Redis
//配置信息并连接
$redisClient->connect('127.0.0.1', 6379, function(swoole_redis $redis, $result) {
    echo "connect:".PHP_EOL;
    if ($result === false) {
        //打出错误的信息
        var_dump($redis->errMsg);
        die;
    }
    var_dump($result);
    $redis->get('aa', function(swoole_redis $redisClient, $result) {
        var_dump($result);
        $redisClient->close();
    });


});
echo "start".PHP_EOL;

    结果返回:

 

    

 

    

 

 


 

 

 

 


 


 


 

 

 

<think>好的,我现在需要给用户介绍一下PHP的Swoole扩展。首先,我得回忆一下自己了解的Swoole相关知识,确保信息准确。Swoole是一个高性能的异步、协程化网络通信引擎,对吧?它能够让PHP具备处理高并发的能力,类似于Node.js或者Go语言的效果。用户可能想知道它的主要特点、应用场景以及和传统PHP的区别。 首先,我应该从基本概念开始。Swoole是用C语言编写的PHP扩展,这意味着它需要安装并启用才能使用。然后,它的核心特性包括异步非阻塞IO、协程支持、多线程模式等等。需要解释这些技术术语,比如异步非阻塞IO如何提高并发处理能力,协程如何更高效地管理线程资源。 接下来,用户可能关心使用Swoole能做什么。比如开发高性能的WebSocket服务器、HTTP服务器、TCP/UDP服务器,或者实现实时应用如聊天室、游戏服务器等。这时候可以举一些例子,比如用Swoole轻松处理上万并发连接,而传统PHP可能因为每个请求一个进程的模式导致资源消耗过大。 另外,需要对比传统PHP和Swoole的工作模式。传统PHP是同步阻塞的,每个请求独立处理,而Swoole通过事件循环和异步回调,使得单个进程可以同时处理多个请求,提高了资源利用率。同时,协程的引入让代码可以以同步的方式编写异步逻辑,降低了开发复杂度。 还要提到Swoole的安装和配置,可能用户会想知道如何开始使用。比如通过PECL安装,或者编译安装,以及需要注意的PHP版本兼容性问题。可能还要提到一些常见的依赖,比如需要安装某些系统库。 然后,可以给出一个简单的代码示例,比如创建一个HTTP服务器,这样用户能直观看到Swoole的代码结构。比如使用Swoole\Http\Server类,定义onRequest事件回调,处理请求和返回响应。确保示例代码符合规范,使用$$...$$格式的数学表达式,但可能这里不需要数学,但要注意用户提到的LaTeX语法正确,不过代码块可能用反引号或者其他方式,但用户给的系统指令里要求行内数学表达式用$...$,独立公式用$$...$$。可能这里主要涉及代码示例,需要确认是否需要使用LaTeX格式,但代码示例一般用代码块,可能需要用其他方式处理,但用户给的指令可能主要针对数学公式。所以可能代码示例正常写,但要注意其他部分如果有数学表达式,比如算法中的公式,需要用指定格式。 另外,需要强调Swoole的优势和适用场景,比如高并发、长连接应用,以及可能的不适用场景,比如简单的CRUD应用可能不需要。还要提到一些注意事项,比如Swoole的进程模型需要避免共享资源冲突,以及代码热重载的问题,因为传统的PHP脚本是每个请求重新加载,而Swoole常驻内存,需要特别注意内存泄漏和代码更新机制。 可能还需要提到Swoole的协程特性,从4.0版本开始支持的协程,可以使用go关键字创建协程,以及协程调度器如何工作,让开发者以同步的方式写异步代码,提高可读性和维护性。比如对比传统的回调地狱,协程让代码更简洁。 然后,要涵盖Swoole的组件和功能,比如内置的异步TCP/UDP/HTTP客户端,进程管理,定时器,Table内存表等。这些组件如何帮助开发者构建高性能应用。 最后,总结一下Swoole的优势,比如提升性能,扩展PHP的能力,但也需要学习新的编程模式和注意事项。可能还要提到社区和文档资源,方便用户进一步学习。 现在需要确保回答结构清晰,分点说明,逐步深入,帮助用户理解。同时要使用中文,符合格式要求,特别是数学表达式的部分,但在这个主题中可能涉及较少,如果有算法或公式出现,要正确应用LaTeX格式。例如,如果有提到性能计算公式,比如QPS的计算,可能需要用$$QPS = \frac{Requests}{Time}$$,但不确定是否必要。不过根据用户的问题,可能不需要数学公式,所以重点放在文字描述和代码示例的结构上。 检查是否有遗漏的重要点,比如Swoole的事件驱动架构,与传统LAMP栈的区别,是否支持协程,如何实现并行处理等。同时,可能用户会关心学习曲线,是否有足够的资源和支持,可以提到官方文档、社区论坛、案例等。 总结思考过程后,组织成一个结构化的回答,分点介绍Swoole的定义、核心特性、应用场景、与传统PHP的对比、安装与使用示例、注意事项等部分,确保信息准确且易于理解。</think>以下是关于PHP Swoole的详细介绍,按逻辑分步说明: --- ### 一、Swoole的定义 **Swoole** 是一个由C语言编写的**PHP扩展**,专注于为PHP提供高性能的异步、协程化网络通信能力。它使PHP突破传统同步阻塞模型的限制,支持开发高并发、实时性强的网络应用(如WebSocket服务、微服务等)。 --- ### 二、核心特性 1. **异步非阻塞I/O** - 基于事件循环(Event Loop),单进程可处理多个并发请求。 - 示例场景:同时处理数千个WebSocket连接,而无需多进程/多线程。 2. **协程(Coroutine)支持** - 用同步代码风格编写异步逻辑,避免“回调地狱”。 - 示例代码: ```php go(function () { $result = co::exec("SELECT * FROM users"); echo $result; }); ``` 3. **多协议支持** 内置HTTP/WebSocket/TCP/UDP服务器及客户端,支持自定义协议。 4. **高性能进程管理** - 支持多进程/多线程模式,充分利用多核CPU。 - 提供进程间通信(IPC)和共享内存(Table)机制。 --- ### 三、与传统PHP的对比 | 特性 | 传统PHP(FPM模式) | Swoole | |---------------------|--------------------------|----------------------------| | **运行模式** | 同步阻塞,每个请求独立进程 | 异步非阻塞,长驻内存 | | **并发能力** | 低(依赖进程数) | 高(单进程处理数千连接) | | **适用场景** | 短连接、低并发Web应用 | 实时通信、微服务、高并发任务 | | **资源消耗** | 高(频繁创建销毁进程) | 低(资源复用) | --- ### 四、典型应用场景 1. **实时通信服务** - 聊天室、在线游戏、即时推送(如WebSocket)。 2. **高性能API/微服务** - 处理高并发HTTP请求,响应时间可缩短至毫秒级。 3. **异步任务系统** - 耗时操作(如文件处理、网络请求)异步化,提升吞吐量。 4. **分布式系统中间件** - 构建RPC服务、连接池、消息队列等。 --- ### 五、安装与使用示例 1. **安装方式** ```bash # 通过PECL安装 pecl install swoole # 或编译安装 phpize && ./configure && make && make install ``` - 要求:PHP ≥7.2,Linux/Unix环境(Windows支持有限)。 2. **简单HTTP服务器示例** ```php <?php $server = new Swoole\Http\Server("0.0.0.0", 9501); $server->on("request", function ($request, $response) { $response->header("Content-Type", "text/plain"); $response->end("Hello Swoole!"); }); $server->start(); ``` - 启动后访问 `http://localhost:9501` 即可测试。 --- ### 六、注意事项 1. **代码热更新** Swoole服务长驻内存,修改代码需重启服务(可通过`reload`信号部分重启)。 2. **避免全局变量** 不同请求可能共享进程内存,需谨慎使用全局状态。 3. **协程环境兼容性** 部分PHP原生函数(如`sleep()`)会阻塞协程,需替换为Swoole的异步版本(如`Co::sleep()`)。 --- ### 七、学习资源 - **官方文档**:[https://www.swoole.co.uk/](https://www.swoole.co.uk/) - **GitHub仓库**:[https://github.com/swoole/swoole-src](https://github.com/swoole/swoole-src) - **社区支持**:活跃的中文社区(如QQ群、论坛)和丰富的中文教程。 --- ### 总结 Swoole通过异步非阻塞与协程技术,大幅提升了PHP在高并发场景下的性能,使其能够胜任实时通信、微服务等复杂任务。但其编程模式与传统PHP差异较大,需掌握事件驱动、资源管理等新概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值