page contents

swoole 第6次课-1再画瓢:机器人案例及多端口监听2

机器人案例,多端口监听 22)正式开始案例 实现思路:在上面的基础上,改造后台服务,不再仅仅是通过receive的 send消息给机器服务,并且通过监听服务,根据业务需求,来控制机器服务操作(包括关闭机器服务)...

接上

22)正式开始案例

实现思路:在上面的基础上,改造后台服务,不再仅仅是通过receive的 send消息给机器服务,并且通过监听服务,来控制机器服务(关闭机器服务)

attachments-2020-12-CKpAVjeB5fd490f450ad2.png

具体实现

目录结构

attachments-2020-12-D4SC1RQO5fd1fe6b3d6d6.png

后台服务class\062\jhymachine\admin\AdminServer.php  主要在上面基础上,改造了recieve,并增加了外界客户发送的指令方法,指令方法里给外界客户发信息或通过监听服务停止机器服务

<?php
use \Swoole\Server;
class AdminServer{
private $port='9501';
private $host='0.0.0.0';
private $server;

public function __construct()
{
echo swoole_get_local_ip()['ens33'].":".$this->port."\n";
$this->server=new Server($this->host,$this->port);
$this->onEvent();
}
public function onEvent(){
$this->server->on("connect",[$this,'connect']);
$this->server->on("receive",[$this,'receive']);
$this->server->on("close",[$this,'close']);
}
public function connect($server, $fd){
echo "Client_{$fd}:Connect to AdminServer.\n";
}
public function receive($server, $fd, $from_id, $data){
/*echo "AdminServer服务,接收到机器服务转发自外界的数据\n";
var_dump($data);
$server->send($fd, 'data of AdminServer back : '.$data); //admin 的server发送的信息*/

echo "AdminServer服务,接收到外界客户端的数据\n";
var_dump($data);
//解码 为数组
$data=json_decode($data,true);
$this->{$data['method']}($server, $fd, $from_id, $data);
}

//定义外界客户端发送数据的指令操作方法1 machineInfo 普通返回给外界的信息方法
public function machineInfo($server, $fd, $from_id, $data)
{
//处理数据 略
echo "给外界客户端tcpClient即client_{$fd}发送消息中……\n";
$server->send($fd,json_encode(['code'=>200,'msg'=>'return ok info from AdminServer']));
echo "给外界客户端tcpClient即client_{$fd}发送消息完毕\n";
}

//定义外界客户端发送数据的指令操作方法2 machineStop 通过监控服务停止机器服务,并或 发送信息给客户端或
public function machineStop($server, $fd, $from_id, $data)
{
if($data['code'] == 9) {
echo "根据外界客户指令,通过监控服务停止机器服务中……\n";
$return = $this->sendToMachine('127.0.0.1', 9556, json_encode($data));
echo "机器服务已停止\n";
$server->send($fd, json_encode(['code' => 200, 'msg' => 'return machineServer stop info from AdminServer']));
}
if($data['code'] == 0) {

/*echo "根据外界客户指令,通过监控服务给外界客户端发送信息中……\n";
$return = $this->sendToMachine('127.0.0.1', 9556, json_encode($data));
echo "已发送信息到监控服务\n";*/

/* 注意:不能通过监控服务给外界客户端发送消息,无论是$server(即Listen),还是$this->server(MacherServer) */

//故这里直接返回消息给外界客户端
$server->send($fd, json_encode(['code' => 200, 'msg' => 'return info from AdminServer']));
}

}

//发送指令给监控服务
public function sendToMachine($ip,$port,$data)
{
$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect($ip, $port, -1)) { //连接到Listen服务
exit("connect failed. Error: {$client->errCode}\n");
}
$client->send($data);
$return = $client->recv();

//$client->close();
}

public function close($server,$fd)
{
echo "Client_{$fd}:Connect of AdminServer is Close.\n";
}

public function start()
{
echo "AdminServer is start\n";
$this->server->start();
}

}

(new AdminServer())->start();

监听服务 class\062\jhymachine\machine\Listen.php  在上面的基础上,改造receive方法,增加逻辑判断,根据指令及code,关闭机器服务

<?php

use \Swoole\Server;

class Listen
{
private $port = '9556';
private $host = '127.0.0.1';
private $server;
private $listen;

public function __construct($server)
{
$this->server=$server;
echo "监听:".$this->host. ":" . $this->port . "\n";
//多端口监听
$this->listen=$server->listen($this->host,$this->port,SWOOLE_SOCK_TCP);
$this->onEvent();
}

public function onEvent()
{
$this->listen->on("connect", [$this, 'connect']);
$this->listen->on("receive", [$this, 'receive']);
$this->listen->on("close", [$this, 'close']);
}

public function connect($server, $fd)
{
echo "Client_{$fd}:Connect to ListenServer.\n";
}

public function receive($server, $fd, $from_id, $data)
{
echo "接收到后台服务转发自外界的指令\n";
$data=json_decode($data,true);
if($data['code'] == 9){
echo "后台服务转发自外界的指令,现在停止\n";
$this->server->shutdown();
}else{
/* 注意:不能通过监控服务给外界客户端发送消息,无论是$server(即Listen),还是$this->server(MacherServer) */
//echo "通过监控服务给外界客户端发送消息中……\n"; //不能通过监控服务给客户端发
//$server->send($fd,"return info form Listen throwing AdminServer"); //这里信息发过这去 无论是$server(即Listen),还是$this->server(MacherServer)
//$this->server->send($fd,"return info form Listen throwing AdminServer"); //这里信息发过这去,同上
//echo "后台服务给{$fd}发达完毕\n";
}
}

public function close($server, $fd)
{
echo "Client_{$fd}:Connect of ListenServer is Close.\n";
}

}

机器服务:class\062\jhymachine\machine\MachineServer.php,与21)基本一样

<?php
require 'Listen.php';
use \Swoole\Server;

class MachineServer
{
private $port = '9505';
private $host = '0.0.0.0';
private $server;

public function __construct()
{
echo swoole_get_local_ip()['ens33'] . ":" . $this->port . "\n";
$this->server = new Server($this->host, $this->port);
//多端口监听
(new Listen($this->server)) ;
$this->onEvent();
}

public function onEvent()
{
$this->server->on("connect", [$this, 'connect']);
$this->server->on("receive", [$this, 'receive']);
$this->server->on("close", [$this, 'close']);
}

public function connect($server, $fd)
{
echo "Client_{$fd}:Connect to MachineServer.\n";
}

public function receive($server, $fd, $from_id, $data)
{
echo "MachineServer服务,接收到外界客户端的数据\n";
var_dump($data);
//转发给后台服务器 AdminServer
$return=$this->sendToAdmin('192.168.204.168',9501,$data);
var_dump($return);
//回信息给客户端
$server->send($fd, 'MachineServer转为自 '.$return); //admin 的server发送的信息
//$server->close($fd);
}

public function sendToAdmin($ip,$port,$data)
{
$client = new \Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect($ip, $port, -1)) { //连接到AdminServer
exit("connect failed. Error: {$client->errCode}\n");
}
$client->send($data);
$return = $client->recv(); //AdminServer返回的信息
$client->close();
return $return;
}

public function close($server, $fd)
{
echo "Client_{$fd}:Connect of MachineServer is Close.\n";
}

public function start()
{
echo "MachineServer is start\n";
$this->server->start();
}

}

(new MachineServer())->start();

外界客户:class\062\jhymachine\tcpClient.php  切换注释,改连后台服务,并构造发送数据,定义指令等数据

<?php
$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('192.168.204.168', 9501, -1)) { //连接到AdminServer
//if (!$client->connect('192.168.204.168',9505, -1)) { //连接到MachineServer
exit("connect failed. Error: {$client->errCode}\n");
}
$data = array(
'method'=>'machineInfo',
//'method'=>'machineStop',
'msg'=>'jihongye',
'data'=>'666',
'code'=>9,
//'code'=>0,
);
$client->send(json_encode($data));
echo $client->recv();
echo "\n";
$client->close();


运行1 :运行后台服务,外界服务,及客户端

attachments-2020-12-ULkcgwFD5fd47b3b4e31e.png运行2: tcpClient.php中切换method方法,运行后台服务、机器服务及客户端

attachments-2020-12-U4Do4cKa5fd47b2a16edd.png运行3: tcpClient.php中切换code值,运行后台服务、机器服务及客户端

attachments-2020-12-lgaVqOKm5fd47b196a2ea.png

至此,功能实现完毕

注意:

1).后台服务machineStop方法中法 if($data['code'] == 0)部分,不能通过监控服务给外界客户端发送消息,若发送消息,可在这里直接 send,无须跳到控制服务中去发送,而且也发不过去,见2)

2)监控服务receive方法中的if($data['code'] == 9)的else部分,不能通过监控服务给外界客户端发送消息,无论是$server(即Listen),还是$this->server(MacherServer服务)


  • 发表于 2020-12-12 11:22
  • 阅读 ( 510 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
吉洪叶
吉洪叶

21 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1320 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章