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

前面主要讲了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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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++;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

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

然后接受客户端的数据的监听的方法变成了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 数据 给 Finish
    return "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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

再看下进程

$ 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

发现启动了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 1
Data: 0

Task 0 Handle 0 times...
Task 0 Handle 1 times...

#task finish
Task 0 finish
Result: Task 0's result
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

client

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

参考资料:

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

 
 
posted @ 2017-08-11 14:10  阿拉善的樵夫  阅读(324)  评论(0编辑  收藏  举报