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

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

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效