SwooleTCP


title: SwooleTCPUDP
date: 2020-01-10 16:13:22
categories:

  • Swoole
    tags:
  • SwooleTCP

创建TCP服务器

TCP官网示例

Server函数示例

PhpStorm配置sftp

#创建文档目录
mkdir -p /home/work/hdtocs
  • 点击菜单Tools=>Deployment=>Browser Remote Host
  • 点击... 进行配置sftp
  • 输入服务器(虚拟机)ip,ssh端口(默认22),账号密码
  • 点击mapping,配置Deployment Path,这个目录将对应现在的项目目录,相当于项目中的文件,通过上传可直接上传到这个配置的目录
  • 配置自动上传,点击菜单Tools=>Deployment=>Automatic Upload
  • 修改文件,在虚拟机中查看,文件已被成功上传

文件/home/work/hdtocs/demo/server/tcp.php内容如下

<?php
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new SwooleServer("127.0.0.1", 9501);

$serv->set([
   'worker_num' =>4 , // worker进程数,建议是CPU核数的1到4倍
    'max_request' => 10000, // 设置最大请求数
]);

//监听连接进入事件
//$fd就是客户端连接服务器的唯一标识
//$reactor_id 线程id
$serv->on('Connect', function ($serv, $fd,$reactor_id) {
    echo "Client:线程id:{$reactor_id}--连接标识:{$fd} Connect.
";
});


//监听数据接收事件
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) {
    $serv->send($fd, "Server: 线程id:{$reactor_id}--连接标识:{$fd} 你输入的输入内容".$data);
});

//监听连接关闭事件
$serv->on('Close', function ($serv, $fd) {
    echo "Client: Close.
";
});

//启动服务器
$serv->start();

服务查看

#开启服务
php tcp.php
#查看端口
ss -lnatup | grep 9501
#开启新终端,连接服务端
nc 127.0.0.1 9501
############服务端显示结果###########
#Client:线程id:0--连接标识:1 Connect.
####################################
#############客户端输入内容###########
#我是nc
####################################
#############客户端显示内容##########
#Server: 线程id:0--连接标识:1 你输入的输入内容我是nc
####################################
#开启新终端,连接服务端
telnet 127.0.0.1 9501
############服务端显示结果###########
#Client:线程id:0--连接标识:2 Connect.
####################################
#客户端输入内容
#############客户端输入内容###########
#我是telnet
####################################
############客户端显示内容###########
#Server: 线程id:0--连接标识:2 你输入的输入内容我是telnet
####################################

PHP四种回调函数方法

地址

匿名函数

$server->on('Request', function ($req, $resp) use ($a, $b, $c) {
    echo "hello world";
});

类静态方法

class A
{
    static function test($req, $resp)
    {
        echo "hello world";
    }
}
$server->on('Request', 'A::Test');
$server->on('Request', array('A', 'Test'));

函数

function my_onRequest($req, $resp)
{
    echo "hello world";
}
$server->on('Request', 'my_onRequest');

对象方法

class A
{
    function test($req, $resp)
    {
        echo "hello world";
    }
}

$object = new A();
$server->on('Request', array($object, 'test'));

创建TCP客户端

<?php
// 连接 swoole tcp 服务
$client = new swoole_client(SWOOLE_SOCK_TCP);

if (!$client->connect("127.0.0.1",9501)){
    echo "连接失败";
    exit;
}
// php cli 常量
// 向命令行打印内容
fwrite(STDOUT,'请输入消息:');
// 获取输入内容
$msg = trim(fgets(STDIN));

// 发送消息给服务器
$client->send($msg);

// 接收来自Server的数据

$result = $client->recv();

echo $result;
echo "";

执行结果如下

#客户端主动连接
php client/tcp_client.php
#输入123
#######返回结果如下##################################################
#Server: 线程id:0--连接标识:6 你输入的输入内容123
####################################################################

查看worker-num参数是否生效

简单解释几个标示符

S 处于休眠状态
l(小写字母L) 多线程,multi-threaded
D 不可中断
R 正在运行,或队列中的进程
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核2.6以后无效)
X 死掉的进程
< 高优先级进程
N 低优先级进程
L 有些页被锁进内存
s 包含子进程
+ 位于后台的进程组
ps -aft | grep [p]hp
  7128 pts/0    Sl+    0:00  \_ php tcp.php
  7129 pts/0    S+     0:00      \_ php tcp.php
  7131 pts/0    S+     0:00          \_ php tcp.php
  7132 pts/0    S+     0:00          \_ php tcp.php
  7133 pts/0    S+     0:00          \_ php tcp.php
  7134 pts/0    S+     0:00          \_ php tcp.php

Swoole热更新

方式一:reload

//监听数据接收事件
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) {
// 当接收到客户端消息时更新代码,下次执行时work代码变化,本次执行还是不变
    $serv->reload();
    $serv->send($fd, "Server: 线程id:{$reactor_id}--连接标识:{$fd} 你输入的输入内容".$data);
});

方式二:shell脚本方式

php代码定义进程名称reload_master

//对于现在的我来说,比较复杂,这样先记录下
public function onStart($serv){
	echo "Start
";
	cli_set_process_title("reload_master");
}

shell脚本reload.sh

#!/bin/bash
echo "loading..."
pid=$(pidof reload_master)
kill -USR1 ${pid}
echo "Reloaded"

每次重启服务时,需要手动执行脚本

#假设代码改变了
#执行重启操作
sh reload.sh

创建UDP服务端

<?php
// 创建serv对象,监听127.0.0.1 9501端口
$serv = new SwooleServer('127.0.0.1',9501,SWOOLE_BASE,SWOOLE_SOCK_UDP);

$serv->set([
   'worker_num'=>4,     // 设置worket进程数
   'max_request'=>1000, // 设置最大请求数
]);

// 接收数据,返回数据
$serv->on('Packet',function ($serv,$data,$clientInfo){
    echo "客户端输入内容:".$data;
   $serv->sendto($clientInfo['address'],$clientInfo['port'],'Swoole:'.$data);
});

$serv->start();

创建UDP客户端

<?php
function send($msg){
    $client = new SwooleClient(SWOOLE_SOCK_UDP);
    if(!$client->connect("127.0.0.1",9501)){
        echo "连接失败";
        exit;
    }else{
        echo '连接成功';
    }
    // 发送消息给服务器
    $client->send($msg.PHP_EOL);
    // 接收来自Server的数据
    echo $client->recv();
    echo PHP_EOL;
}

while (true){
    // php cli 常量
    // 向命令行打印内容
    fwrite(STDOUT,"请输入内容:");
    // 获取输入内容
    $msg = trim(fgets(STDIN));

    if ($msg == "quit"){
        break;
    }else{
        send($msg);
    }
}

原文地址:https://www.cnblogs.com/anyux/p/12202055.html