【swoole做一个TCP中转服务,相互转发】

设计背景:

一台内网的TCP终端设备,需要将设备传输到外网的TcpServer服务器上,中间架设一台双网口的电脑,作为转发服务器

设计思路:

在中转服务器起一个tcpserver服务,当tcp终端连接的时候,起一个tcp_client客户端连接到外网的tcpserver服务器

代码如下:

<?php

//error_reporting(0);
use Swoole\Coroutine\Client;
use Swoole\Coroutine\Channel;
use Swoole\Coroutine;
use function Swoole\Coroutine\run;

global $server;
$server = new \Swoole\Server('127.0.0.1', 9503);

$server->on('start', function ($server) {
    echo "TCP Server is started at tcp://127.0.0.1:9503\n";
});


$server->on('connect', function ($server, $fd) {
    echo date("Y-m-d H:i:s") . ":" . "钻机接入:connection open: {$fd}\n";
    #1、监听钻机连接,记录其fd为$fd 并将其global
    #2、如果钻机接入,就开始请求连接服务器,记录其client为$tcp_client 并将其global
    #3、如果收到钻机的消息,则转发给服务器,如果收到服务器的响应,则转发给钻机
    global $zj_fd;
    $zj_fd = $fd;
    global $tcp_client;
    $tcp_client = new Client(SWOOLE_SOCK_TCP);
    if (!$tcp_client->connect('192.168.0.126', 24001)) {
        $tcp_client->close();
        dump("连接服务端失败,此时说明客户端连接上来了,但无法连接到服务端,请检查服务端是否正常运行");
        //$server->close($fd);
    }
    #调用协程--接收来自服务端的消息,并将其转发给钻机
    server_data();
});

$server->on('receive', function ($server, $fd, $reactor_id, $data) {
    global $tcp_client;
    if ($tcp_client->isConnected()) {
        $tcp_client->send($data);
        dump("收到钻机消息,并转发给服务器:" . bin2hex($data));
    } else {
        if (!$tcp_client->connect('192.168.0.126', 24001)) {
            $tcp_client->close();
            dump("服务器中转连接失败,此时说明客户端有数据上来,但是发不到服务端去了,请检查服务端是否正常运行");
            //$server->close($fd);
        }
    }

});


$server->on('close', function ($server, $fd) {
    dump("connection close: {$fd}\n");
    global $tcp_client;
    $tcp_client->close();
});
$server->start();

function server_data()
{
    //开启通道
    $channel = new Channel(1);
    Coroutine::create(function () use ($channel) {
        while (true) {
            global $tcp_client;
            if (!$tcp_client->isConnected()) {
                if (!$tcp_client->connect('192.168.0.126', 24001)) {
                    $tcp_client->close();
                    dump("客户端与服务器的连接是断开状态,此处说明是服务端宕机了,连不上了,请联系服务端管理人员😱");
                    //$server->close($fd);
                    continue;
                } else {
                    dump("服务器中转连接成功========😊");
                }
            }
            if ($tcp_client->isConnected()) {
                //var_dump("连接正常\r\n");
                $server_data = $tcp_client->recv();
                global $server;
                global $zj_fd;
                if (strlen($server_data) > 0) {
                    dump("收到服务器消息,并转发给钻机:" . bin2hex($server_data));
                    $server->send($zj_fd, $server_data);
                } else {
                    if ($tcp_client->errCode !== SOCKET_ETIMEDOUT) {
                        $tcp_client->close();
                        dump("服务器中转连接失败444");
                        //$server->close($fd);
                    }
                    dump("与服务端的实际连接断开,每隔1秒检测重连一下");
                    Coroutine::sleep(1);
                }
            }
        }
    });
}

function dump($msg)
{
    echo date("Y-m-d H:i:s") . ":" . $msg . PHP_EOL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炼气三千年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值