Server
- UDP服务器创建与TCP服务器创建类型,但不同的是:UDP没有连接的概念。启动Server后,客户端无需Connect,直接可以向Server监听的9502端口发送数据包。对应的事件为onPacket。
<?php
/**
* User: sHuXnHs <hexiaohongsun@gmail.com>
* Date: 19-7-12
* Time: 17:47
*/
class UDP{
private $sock_type = SWOOLE_SOCK_UDP;
protected $config = [
'worker_num' => '8', // worker进程数
'max_conn' => '1000', // 最大连接数
'daemonize' => '1', // 开启转入后台守护进程运行
'reactor_num' => '8', // 线程数量
'max_request' => '1000', // 最大请求数,表示worker进程在处理n次请求后结束运行,设置为0表示不自动重启
'log_file' => '/var/log/swoole.log', // 指定swoole错误日志文件
];
public $serv = null;
/**
* UDP constructor.
* @param string $host host
* @param int $port port
* @param int $mode 默认为多线程模式,还有SWOOLE_BASE基本模式
*/
public function __construct($host = '127.0.0.1', $port = 9502, $mode = SWOOLE_PROCESS)
{
$this->serv = new swoole_server($host, $port, $mode, $this->sock_type);
// 设置运行的各项参数
$this->serv->set($this->config);
// UDP没有连接概念,直接向Server发送数据包
$this->serv->on("Packet", [$this, 'onPacket']);
// 开启事件
$this->serv->start();
}
/**
* @function 监听接收到UDP数据包事件
* @param object $serv server对象
* @param string $data 收到的数据文件,可能是文本或二进制内容
* @param array $clientInfo 客户端的相关信息,是一个数组,有客户端的IP和端口等内容
*/
public function onPacket($serv, $data, $clientInfo) {
$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
var_dump($clientInfo);
}
}
$serv = new UDP();
Client
可以直接使用前面TCP的客户端,new的时候传入new Client(“127.0.0.1”, “9502”, SWOOLE_SOCK_UDP);
<?php
/**
* 客户端
* User: sHuXnHs <hexiaohongsun@gmail.com>
* Date: 19-7-12
* Time: 16:47
*/
class Client{
public $client = null;
public $config = [];
/**
* Client constructor.
* @param string $host host
* @param int $port port
* @param int $sock_type socket的类型,默认TCP,也可以UDP:SWOOLE_SOCK_UDP
* @param int $is_async 默认同步阻塞,也可以指定为SWOOLE_SOCK_ASYNC异步非阻塞或SWOOLE_SOCK_SYNC同步阻塞
* @param bool $is_keep 是否创建长连接
*/
public function __construct($host = '127.0.0.1', $port = 9501, $sock_type = SWOOLE_SOCK_TCP,
$is_async = SWOOLE_SOCK_ASYNC, $is_keep = false)
{
if($is_keep){
$this->client = new Swoole\Client($sock_type | SWOOLE_KEEP, $is_async);
}else{
$this->client = new Swoole\Client($sock_type, $is_async);
}
// 设置运行的各项参数
$this->client->set($this->config);
// 注册异步事件回调函数
$this->client->on("connect", [$this, 'onConnect']);
$this->client->on("receive", [$this, 'onReceive']);
$this->client->on("error", [$this, 'onError']);
$this->client->on("close", [$this, 'onClose']);
// 开启事件
$this->client->connect($host, $port);
}
/**
* @function 监听连接进入事件
* @param object $cli client对象
*/
public function onConnect($cli){
fwrite(STDOUT, "input data to server");
$data = trim(fgets(STDIN));
$cli->send($data);
}
/**
* @function 监听事件接受数据
* @param object $cli client对象
* @param string $data 接收到的数据
*/
public function onReceive($cli, $data){
echo "Receive data: ".$data.PHP_EOL;
}
/**
* @function 监听连接关闭事件
* @param object $cli client对象
*/
public function onClose($cli){
echo "Connection close".PHP_EOL;
}
/**
* @function 监听事件错误
* @param object $cli client对象
*/
public function onError($cli){
echo "error".$cli->errCode.PHP_EOL;
}
}
//$client = new Client();
$client = new Client("127.0.0.1", "9502", SWOOLE_SOCK_UDP);
跑一下看看
顺便打印出$clientInfo,可以看到客户端信息数组包含了:
- server_socket:数值可以参考Swoole官方文档
- server_port
- address
- port