[关闭]
@phper 2016-12-09T11:04:30.000000Z 字数 2934 阅读 4750

swoole深入学习 3. upd Server和udp Client

swoole


前面主要讲了tcp得server和client的业务处理,tcp有三次握手,有连接的概览,而UDP服务器与TCP服务器不同,UDP没有连接的概念。启动Server后,客户端无需Connect,直接可以向Server监听的端口发送数据包。server 接受数据的事件为onPacket, 发送给client的方法变成sendto

udp Server

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: yangyi
  5. * Date: 2016/12/7
  6. * Time: 18:02
  7. */
  8. //创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP
  9. $serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP);
  10. //监听数据发送事件
  11. $serv->on('Packet', function ($serv, $data, $clientInfo) {
  12. //发送给客户端 用sendto
  13. $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
  14. var_dump($data);
  15. });
  16. //启动服务器
  17. $serv->start();

udp client

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: yangyi
  5. * Date: 2016/12/7
  6. * Time: 18:02
  7. */
  8. $client = new Swoole\Client(SWOOLE_SOCK_UDP);
  9. $client->connect('127.0.0.1', 9503, 1);
  10. $i = 0;
  11. while ($i < 1000) {
  12. $client->send($i."\n");
  13. $message = $client->recv();
  14. echo "Get Message From Server:{$message}\n";
  15. $i++;
  16. }

上面server启动之后,会启动一个进程,默认不是4个,就一个主进程,来处理数据。

  1. pstree |grep server.php
  2. | | \--= 87143 yangyi php udp_server.php

然后接受客户端的数据的监听的方法变成了Packet了,而不是Receive。发送数据给client 的方法为sendto。需要客户端的地址和端口。这点和tcp不一样,没有fd的概念。

$serv->sendto($clientInfo['address'], $clientInfo['port'], "something");

如果业务请求量很大,一个worker 肯定是不够的,我们利用多个task worker的方式来改写下server。

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: yangyi
  5. * Date: 2016/12/7
  6. * Time: 18:02
  7. */
  8. //创建Server对象,监听 127.0.0.1:9503端口,类型为SWOOLE_SOCK_UDP
  9. $serv = new Swoole\Server("127.0.0.1", 9503, SWOOLE_BASE, SWOOLE_SOCK_UDP);
  10. $serv->set([
  11. 'worker_num' => 4, # 4个worker
  12. 'task_worker_num' => 4, # 4个task
  13. 'deamonize' => false,
  14. ]);
  15. //监听数据发送事件
  16. $serv->on('Packet', function ($serv, $data, $clientInfo) {
  17. $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
  18. var_dump($clientInfo, $data);
  19. //把任务丢给task
  20. $serv->task($data);
  21. });
  22. $serv->on('Task', function ($serv, $task_id, $from_id, $data) {
  23. echo "This Task {$task_id} from Worker {$from_id}\n";
  24. echo "Data: {$data}\n";
  25. //模拟慢io查询、
  26. for($i = 0 ; $i < 2 ; $i ++ ) {
  27. sleep(1);
  28. echo "Task {$task_id} Handle {$i} times...\n";
  29. }
  30. //return 数据 给 Finish
  31. return "Task {$task_id}'s result";
  32. });
  33. $serv->on('Finish', function ($serv,$task_id, $data) {
  34. echo "Task {$task_id} finish\n";
  35. echo "Result: {$data}\n";
  36. });
  37. //启动服务器
  38. $serv->start();

再看下进程

  1. $ pstree |grep server.php
  2. | | \-+= 88426 501 php udp_server.php #master
  3. | | \-+- 88427 501 php udp_server.php #manager
  4. | | |--- 88428 501 php udp_server.php #worker、task
  5. | | |--- 88429 501 php udp_server.php
  6. | | |--- 88430 501 php udp_server.php
  7. | | |--- 88431 501 php udp_server.php
  8. | | |--- 88432 501 php udp_server.php
  9. | | |--- 88433 501 php udp_server.php
  10. | | |--- 88434 501 php udp_server.php
  11. | | \--- 88435 501 php udp_server.php

发现启动了8个work进程和一个manager进程一个master进程

这样就完成了一个多worker的udp server。

启动server,再启动client。

server

  1. $ php udp_server.php
  2. #打印udp的地址和ip
  3. /Users/yangyi/www/bestPHP/swoole/udp_server.php:22:
  4. array(3) {
  5. 'server_socket' =>
  6. int(4)
  7. 'address' =>
  8. string(9) "127.0.0.1"
  9. 'port' =>
  10. int(55182)
  11. }
  12. #打印客户端发来的数据
  13. /Users/yangyi/www/bestPHP/swoole/udp_server.php:22:
  14. string(2) "0"
  15. #task启动
  16. This Task 0 from Worker 1
  17. Data: 0
  18. Task 0 Handle 0 times...
  19. Task 0 Handle 1 times...
  20. #task finish
  21. Task 0 finish
  22. Result: Task 0's result

client

  1. $ php udp_client.php
  2. #获取server发回的数据
  3. Get Message From Server:Server 0

参考资料:

http://wiki.swoole.com/wiki/page/477.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注