@phper
2016-12-09T03:04:30.000000Z
字数 2934
阅读 5259
swoole
前面主要讲了tcp得server和client的业务处理,tcp有三次握手,有连接的概览,而UDP服务器与TCP服务器不同,UDP没有连接的概念。启动Server后,客户端无需Connect,直接可以向Server监听的端口发送数据包。server 接受数据的事件为onPacket, 发送给client的方法变成sendto。
udp Server
<?php/*** Created by PhpStorm.* User: yangyi* Date: 2016/12/7* Time: 18:02*///创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP$serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP);//监听数据发送事件$serv->on('Packet', function ($serv, $data, $clientInfo) {//发送给客户端 用sendto$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);var_dump($data);});//启动服务器$serv->start();
udp client
<?php/*** Created by PhpStorm.* User: yangyi* Date: 2016/12/7* Time: 18:02*/$client = new Swoole\Client(SWOOLE_SOCK_UDP);$client->connect('127.0.0.1', 9503, 1);$i = 0;while ($i < 1000) {$client->send($i."\n");$message = $client->recv();echo "Get Message From Server:{$message}\n";$i++;}
上面server启动之后,会启动一个进程,默认不是4个,就一个主进程,来处理数据。
pstree |grep server.php| | \--= 87143 yangyi php udp_server.php
然后接受客户端的数据的监听的方法变成了Packet了,而不是Receive。发送数据给client 的方法为sendto。需要客户端的地址和端口。这点和tcp不一样,没有fd的概念。
$serv->sendto($clientInfo['address'], $clientInfo['port'], "something");
如果业务请求量很大,一个worker 肯定是不够的,我们利用多个task worker的方式来改写下server。
<?php/*** Created by PhpStorm.* User: yangyi* Date: 2016/12/7* Time: 18:02*///创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP$serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP);$serv->set(['worker_num' => 4, # 4个worker'task_worker_num' => 4, # 4个task'deamonize' => false,]);//监听数据发送事件$serv->on('Packet', function ($serv, $data, $clientInfo) {$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);var_dump($clientInfo, $data);//把任务丢给task$serv->task($data);});$serv->on('Task', function ($serv, $task_id, $from_id, $data) {echo "This Task {$task_id} from Worker {$from_id}\n";echo "Data: {$data}\n";//模拟慢io查询、for($i = 0 ; $i < 2 ; $i ++ ) {sleep(1);echo "Task {$task_id} Handle {$i} times...\n";}//return 数据 给 Finishreturn "Task {$task_id}'s result";});$serv->on('Finish', function ($serv,$task_id, $data) {echo "Task {$task_id} finish\n";echo "Result: {$data}\n";});//启动服务器$serv->start();
再看下进程
$ pstree |grep server.php| | \-+= 88426 501 php udp_server.php #master| | \-+- 88427 501 php udp_server.php #manager| | |--- 88428 501 php udp_server.php #worker、task| | |--- 88429 501 php udp_server.php| | |--- 88430 501 php udp_server.php| | |--- 88431 501 php udp_server.php| | |--- 88432 501 php udp_server.php| | |--- 88433 501 php udp_server.php| | |--- 88434 501 php udp_server.php| | \--- 88435 501 php udp_server.php
发现启动了8个work进程和一个manager进程一个master进程
这样就完成了一个多worker的udp server。
启动server,再启动client。
server
$ php udp_server.php#打印udp的地址和ip/Users/yangyi/www/bestPHP/swoole/udp_server.php:22:array(3) {'server_socket' =>int(4)'address' =>string(9) "127.0.0.1"'port' =>int(55182)}#打印客户端发来的数据/Users/yangyi/www/bestPHP/swoole/udp_server.php:22:string(2) "0"#task启动This Task 0 from Worker 1Data: 0Task 0 Handle 0 times...Task 0 Handle 1 times...#task finishTask 0 finishResult: Task 0's result
client
$ php udp_client.php#获取server发回的数据Get Message From Server:Server 0
参考资料: