duanhuokuang5280 2016-07-13 11:39 采纳率: 100%
浏览 131
已采纳

PHP安全Websocket客户端麻烦,需要非阻止

I'm building a dashboard that allows me to visualise my crontab as it runs (Think a queue of upcoming tasks, those that are running currently and those that have finished and whether the outcome was successful.) To do this, I need to send messages from the tasks (running or monitored by PHP) on my server, to the client browsers that run the dashboard using javascript. It also has to be secure.

To solve this issue I implemented a Twisted/Autobahn socket server in Python, which worked fine once I had paid for proper security certificates. The problem I have however is getting the PHP running the crontasks to be able to send messages to the webSocket server which passes them on to the client browsers, so far I have hacked this by writing a Python client that accepts the message to send as an argument and run this as an exec from PHP.

Obviously this is not a robust solution (which is also relatively slow to execute) and I'd now like to send logfile entries from the crontasks over websockets to my dashboards so I can see what's happening on my servers as tasks run. I've been looking for a while and tried various approaches (most are too long to post) however they range from tutorials, to segments from the PHP website to libraries such as Thruway (which seems too over-engineered for my use case, specialised and hard to adapt).

The best progress I have so far is Pawl, and using the following code I'm able to successfully send three messages to the Python Socket Server using wss:

<?php

    require __DIR__ . '/vendor/autoload.php';

    \Ratchet\Client\connect('wss://127.0.0.1:9000')->then(function($conn) {
        $conn->on('message', function($msg) use ($conn) {
            echo "Received: {$msg}
";
            $conn->close();
        });

        $conn->send('MSG 1');

        $conn->send('MSG 2');

        $conn->send('MSG 3');

    }, function ($e) {
        echo "Could not connect: {$e->getMessage()}
";
    });
?>

(Note that this depends on the libraries found here)

The problem I have is that I would like to be able to open and close the connection and send messages as separate steps, in the code example (which I've had difficulty adapting) it seems that as open, send and close are all wrapped in the then method and anonymous function I cannot call these methods seperately. Ideally I'd like to open the connection at the beginning of my crontask execution, each time a message is logged call the send method and close the connection at the end without wasting time opening and closing a connection to my socket server for each and every message. Please note that listening for replies isn't necessary.

Also, any solutions that work to 127.0.0.1:9000 over WSS and don't need libraries or use a different one I'm happy to consider. Please also note (after seeing other posts) this question specifically refers to a websocket client, not a server.

Many thanks,

James

  • 写回答

1条回答 默认 最新

  • doushuangai9733 2016-07-22 08:17
    关注

    Leaving this in case anybody else finds this final solution welcome:

    In the end I wrapped a module called Textalk by Fredrik Liljegren et al in a small class to make it more accesible and this solved my issue.

    Here is the code I used in the end:

     require('vendor/autoload.php');
    
     use WebSocket\Client;
    
            class secureSocketClient {
    
                    private $OClient;
    
                    function __construct($VProtocol, $VLocation, $VPort, $VDir) {
    
                            $this->OClient = new Client("$VProtocol://$VLocation:$VPort" . ($VDir != null ? "/$VDir" : ""));
                    }
    
                    function sendMessage($ORequestData) {
    
                            $VLocalMessage = json_encode($ORequestData);
    
                            $this->OClient->send($VLocalMessage);
                    }
    
                    function __destruct() {
    
                            $this->OClient->close();
                    }
            }
    

    Which can be invoked as so:

    require_once <class location>
    
    $this->OSecureSocketClient = new secureSocketClient("wss", "127.0.0.1", "9000", null);
    
    $this->OSecureSocketClient->sendMessage($OMSG1);
    $this->OSecureSocketClient->sendMessage($OMSG2);
    $this->OSecureSocketClient->sendMessage($OMSG3);
    

    To install textTalk (on linux), you can use the following commands in the directory where the class will reside:

    curl -sS https://getcomposer.org/installer | php
    

    add the following to composer.json (in the same directory):

    {
        "require": {
            "textalk/websocket": "1.0.*"
        }
    }
    

    then run the following:

    sudo php composer.phar install
    

    Regards,

    James

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 如何把 16bit Bayer 图像数据转换为 TIFF RGB
  • ¥15 进行基于用户的协同过滤推荐,使用准确率和召回率评价推荐模型的效果
  • ¥15 关于#cesium#的问题:cesium 根据经纬度、高度、方位角、俯仰角和距离求另一点高度
  • ¥15 word脚注设置不起空格符号
  • ¥15 为什么apriori的运行时间会比fp growth的运行时间短呢
  • ¥15 求解密json或者美化
  • ¥15 帮我解决一下膳食平衡的线性规划模型的数据实例
  • ¥40 万年历缺少农历,需要和阳历同时显示
  • ¥250 雷电模拟器内存穿透、寻基址和特征码的教学
  • ¥15 关于Java的学习问题