十一、Swoole 基础学习笔记 - Swoole UDP 服务的使用

作者: 温新

分类: 【Swoole 系列】

阅读: 742

时间: 2023-02-27 07:52:04

hi,我是温新,一名PHPer

文章基于 Swoole 5.0.1 版本编写。

**学习目标:了解 Swoole UDP 的使用 **

说明:本篇文章结合官方文档编写及参考网络资料编写,虽非全部原创,但也是结合了自己的理解,若转载请附带本文 URL,编写不易,持续编写更不易,谢谢!

UDP 与 TCP 有所不同,UDP没有连接的概念。服务启动后,客户端不需要 Connect 就可以直接向 Server 监听的端口发送数据包。服务端使用监听 onPacket 事件。

  • $clientInfo 是一个数组,保存着客户端相关的数据信息,如地址、端口等;
  • 服务端使用 sendto() 方法向客户端发送数据。

UDP 服务端

<?php
// 12-swoole-udp-server.php
$server = new Swoole\Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);

// 监听数据接收事件
$server->on('Packet', function ($server, $data, $clientInfo) {
    // print_r($clientInfo);
    $server->sendto($clientInfo['address'], $clientInfo['port'], 'Server:' . $data);
});

$server->start();

打印 clientInfo 信息如下:

Array
(
    [server_socket] => 4
    [dispatch_time] => 1670861036.5293
    [server_port] => 9501
    [address] => 127.0.0.1
    [port] => 49286
)

连接 UDP 服务端,可以使用:netcat -u 127.0.0.1 9501, 输出信息如下:

$netcat -u 127.0.0.1 9501
hello
Server:hello

UDP 客户端

<?php
// 12-swoole-upd-client.php
$client = new Swoole\Client(SWOOLE_SOCK_UDP);

if (!$client->connect('127.0.0.1', 9501, -1)) {
	exit('连接服务器失败' . $client->errCode . PHP_EOL);
}

$i = 0;
while ($i < 1000) {
    $client->send($i . PHP_EOL);
    $message = $client->recv();
    echo 'get message from server:' . $message . PHP_EOL;
    $i++;
}

UDP 处理耗时任务

如果业务量大,或者任务耗费时间长,那么可以结合异步任务进行处理。

<?php
// 12-swoole-upd-server1.php

$server = new Swoole\Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);

$server->set([
    'worker_num'      => 5,
    'task_worker_num' => 5,
]);

$server->on('Packet', function ($server, $data, $clientInfo) {
    $server->sendto($clientInfo['address'], $clientInfo['port'], 'server:' . $data);

    // 异步处理任务
    $server->task($data);
});

$server->on('Task', function ($server, $taskId, $fromId, $data) {
    // 处理慢任务处理
    for ($i = 0; $i < 3; $i++) { 
        sleep(1);
        echo '任务 '. $taskId . '处理中 ' . $i . '请等待...' . PHP_EOL;
    }

    return '任务 ' . $taskId . PHP_EOL;
});

$server->on('Finish', function ($server, $taskId, $data) {
	echo '任务: ' . $taskId . ' 完成, 数据是 ' . $data . PHP_EOL;
});

$server->start();

我是温新,本篇文章到此结束。

请登录后再评论