注释可以忽略不计 个人加的 可能会有错误 别误导大家。。。
server端
<?php
class Server
{
private $serv;
public function __construct() {
$this->serv = new swoole_server("0.0.0.0", 9501);
$this->serv->set(array(
'worker_num' => 8,
'daemonize' => false,
'max_request' => 10000,
'dispatch_mode' => 2,
'debug_mode'=> 1,
'task_worker_num' => 8,//假设为1后面的task 要排队 如果多一些可以同时处理
/*
单个task的处理耗时,如100ms,那一个进程1秒就可以处理1/0.1=10个task
task投递的速度,如每秒产生2000个task
2000/10=200,需要设置task_worker_num => 200,启用200个task进程
*/
));
$this->serv->on('Start', array($this, 'onStart'));
$this->serv->on('Connect', array($this, 'onConnect'));
$this->serv->on('Receive', array($this, 'onReceive'));
$this->serv->on('Close', array($this, 'onClose'));
// bind callback
$this->serv->on('Task', array($this, 'onTask'));
$this->serv->on('Finish', array($this, 'onFinish'));
$this->serv->start();
}
public function onStart( $serv ) {
echo "Start\n";
}
public function onConnect( $serv, $fd, $from_id ) {
echo "Client {$fd} connect\n";
}
public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
echo "Get Message From Client {$fd}:{$data}\n";
// send a task to task worker.
$param = array(
'fd' => $fd
);
$serv->task( json_encode( $param ) );
echo "Continue Handle Worker\n";
}
public function onClose( $serv, $fd, $from_id ) {
echo "Client {$fd} close connection\n";
}
//function onTask(swoole_server $serv, int $task_id, int $src_worker_id, mixed $data);
public function onTask($serv,$task_id,$from_id, $data) {
echo "This Task {$task_id} from Worker {$from_id}\n";
echo "Data: {$data}\n";
for($i = 0 ; $i < 10 ; $i ++ ) {
sleep(1);
echo "Taks {$task_id} Handle {$i} times...\n";
}
$fd = json_decode( $data , true )['fd'];
$serv->send( $fd , "Data in Task {$task_id}");
return "Task {$task_id}'s result";//这个是返回给 onfinsh里 的结果 就是$data
}
public function onFinish($serv,$task_id, $data) {
echo "Task {$task_id} finish\n";
echo "Result: {$data}\n";
}
}
$server = new Server();
/*
Continue Handle Worker
This Task 0 from Worker 7
Data: {"fd":1}
Taks 0 Handle 0 times...
Taks 0 Handle 1 times...
Taks 0 Handle 2 times...
Taks 0 Handle 3 times...
Taks 0 Handle 4 times...
Taks 0 Handle 5 times...
Taks 0 Handle 6 times...
Taks 0 Handle 7 times...
Taks 0 Handle 8 times...
Taks 0 Handle 9 times...
Task 0 finish
Result: Task 0's result
*/
?>
client:
<?php
class Client
{
private $client;
public function __construct() {
$this->client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
$this->client->on('Connect', array($this, 'onConnect'));
$this->client->on('Receive', array($this, 'onReceive'));
$this->client->on('Close', array($this, 'onClose'));
$this->client->on('Error', array($this, 'onError'));
}
public function connect() {
$fp = $this->client->connect("127.0.0.1", 9501 , 1);
if( !$fp ) {
echo "Error: {$fp->errMsg}[{$fp->errCode}]\n";
return;
}
}
public function onReceive( $cli, $data ) {
echo "Get Message From Server: {$data}\n";
}
public function onConnect( $cli) {
fwrite(STDOUT, "Enter Msg:");//输出到终端
//bool swoole_event_add(mixed $sock, mixed $read_callback, mixed $write_callback = null,int $flags = null);
/*
swoole_event_add函数用于将一个socket加入到底层的reactor事件监听中。此函数可以用在Server或Client模式下。 函数原型:
*/
swoole_event_add(STDIN, function($fp){//输入 假设底层是io多路复用 监听输入描述符
global $cli;//设置全局 不然会报错
fwrite(STDOUT, "Enter Msg:");
$msg = trim(fgets(STDIN)); //去除输入的空格
$cli->send( $msg );// 然后发送消息。。。
});
}
//
public function onClose( $cli) {
echo "Client close connection\n";
}
public function onError() {
}
public function send($data) {
$this->client->send( $data );
}
public function isConnected() {
return $this->client->isConnected();
}
}
$cli = new Client();
$cli->connect();
一些补充说明
onTask回调中,我们通过task_id和from_id(也就是worker_id)来区分不同进程投递的不同task。当一个task执行结束后,通过return一个字符串将执行结果返回给Worker进程。Worker进程将通过onfinsh回调函数接收这个处理结果。