Rumah  >  Artikel  >  pembangunan bahagian belakang  >  利用Swoole同时更新多台服务器的代码

利用Swoole同时更新多台服务器的代码

不言
不言asal
2018-07-06 16:47:462156semak imbas

这篇文章主要介绍了关于利用Swoole同时更新多台服务器的代码,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

一个小型网站的架构, 前面一台负载均衡, 后面几台web服务器. 更新代码成了难题, 一个一个FTP传不现实, 而且容易漏传,导致两个WEB服务器的代码都不一致.

一个简单的想法:

利用Websocket Server发送更新指令, Websocket Client 接收到更新指令, 运行git pull更新代码.

WebSocket Client有几个角色:

  • Solider: 接收命令, 不能发送命令

  • Commander: 发送命令

流程图:

4166444827-5b2875a1b3581_articlex[1].png

部分代码实现:

<?php 
//Server.php
require_once &#39;./Table.php&#39;;

use Swoole\WebSocket\Server as WebSocketServer;

class Server
{
    protected $server;

    protected $table;

    public function __construct($config)
    {
        $this->table = new Table();
        $this->server = new WebSocketServer($config[&#39;host&#39;], $config[&#39;port&#39;]);
        $this->server->set($config[&#39;configuration&#39;]);
        $this->addEventListener();
    }

    public function addEventListener()
    {
        $this->server->on(&#39;open&#39;, Closure::fromCallable([$this, &#39;onOpen&#39;]));
        $this->server->on(&#39;message&#39;, Closure::fromCallable([$this, &#39;onMessage&#39;]));
        $this->server->on(&#39;close&#39;, Closure::fromCallable([$this, &#39;onClose&#39;]));
    }

    private function onOpen($server, $request)
    {
        if ($request->get[&#39;role&#39;] == &#39;commander&#39;) {
            $this->table->commander = $request->fd;
        } else {
            $soliders = $this->table->soliders;

            $soliders[] = $request->fd;

            $this->table->soliders = $soliders;
        }
    }

    private function onMessage($server, $frame)
    {
        if ($frame->fd == $this->table->commander) {
            $command = $frame->data;

            foreach ($this->table->soliders as $solider) {
                $this->server->push($solider, $command);
            }
        } else {
            $this->server->push($frame->fd, "You don not have any right to send message");
        }
    }

    private function onClose($server, $fd)
    {
        $soliders = $this->table->soliders;

        if (in_array($fd, $soliders)) {
            unset($soliders[array_search($fd, $soliders)]);
        }
    }

    public function run()
    {
        $this->server->start();
    }
}

$server = new Server([
    &#39;host&#39; => &#39;0.0.0.0&#39;,
    &#39;port&#39; => 8015,
    &#39;configuration&#39; => [
        &#39;daemonize&#39; => 1,
    ]
]);

$server->run();
<?php 
//Client.php
use Swoole\Http\Client as WebSocketClient;

class Client
{
    protected $protocol;

    protected $host;

    protected $port;

    protected $query;

    protected $client;

    protected $allow_events = [&#39;onOpen&#39;, &#39;onMessage&#39;, &#39;onClose&#39;];

    public function __construct($url)
    {
        list(&#39;scheme&#39; => $this->protocol, &#39;host&#39; => $this->host, &#39;port&#39; => $this->port, &#39;query&#39; => $this->query) = parse_url($url);

        if ($this->protocol == &#39;wss&#39;) {
            echo &#39;unsupport protocol&#39;;
        }

        $this->client = new WebSocketClient($this->host, $this->port);
    }

    public function start(Callable $callback)
    {
        $this->client->upgrade(&#39;/?&#39; . $this->query, $callback);
    }

    public function __set($field, $value)
    {
        if (in_array($field, $this->allow_events) && is_callable($value)) {
            $this->client->on(strtolower(substr($field, 2)), $value);
        } else {
            echo &#39;Unsupport Event&#39;;
        }        
    }
}
<?php 
//Solider.php
require_once &#39;./Client.php&#39;;

function parseCommand($data)
{
    return json_decode($data, true);
}

function updateCommand()
{
    //you can do something here
    exec(&#39;git pull&#39;);
    // exec(&#39;composer update&#39;);
    // exec(&#39;npm install&#39;);
}

$ws = new Client(&#39;ws://192.168.1.142:8015?role=solider&#39;);

$ws->onMessage = function($client, $frame) {
    list(&#39;command&#39; => $command, &#39;params&#39; => $params) = parseCommand($frame->data);

    echo $command;

    switch ($command) {
        case &#39;update&#39;:
            updateCommand();
            break;
    }
};

$ws->onClose = function($client) {

};

$ws->start(function ($client) {
    
});

\Swoole\Process::daemon();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button class="btn btn-primary" onclick="update();">更新</button>

    <script type="text/javascript">
        function update()
        {
            var ws = new WebSocket("ws://192.168.1.142:8015?role=commander");
                
           ws.onopen = function()
           {
              // Web Socket 已连接上,使用 send() 方法发送数据
              ws.send(JSON.stringify({"command": "update", "params": {}}));
           };
            
           ws.onmessage = function (evt) 
           { 
              var received_msg = evt.data;
              alert(received_msg);
           };
            
           ws.onclose = function()
           { 
              // 关闭 websocket
              alert("连接已关闭..."); 
           };


        }
    </script>
</body>
</html>

完整代码:

https://gitee.com/shuizhuyu/P...

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

给PHP开启shmop扩展实现共享内存

使用RoadRunner 加速 Laravel 应用

使用 mixphp 打造多进程异步邮件发送

Atas ialah kandungan terperinci 利用Swoole同时更新多台服务器的代码. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn