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

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

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵