Jump to content

HTTP server with two hosts and same port


Go to solution Solved by kicken,

Recommended Posts

Is there any problem creating two HTTP servers with the same port, but using localhost as one host and the server's static IP as the other?  I've tested it and it seems to be okay.

 

PS.  Why I am doing this....

 

The server runs a socket server service which can be connected by one or more machines which have socket clients which allows bidirectional communication.

 

An Apache HTTP server 192.168.1.200:80 running on the same server receives requests, and needs to forward data to the socket server and onward to the applicable socket client.  To do so, I added a HTTP server 127.0.0.1:1337 to the script which implements the socket server and the scripts on 192.168.1.200:80 make a cURL request to localhost.  (While this works, should I instead use a Redis queue, or some other means to do this???)

 

The machines with the socket clients described above also need to send large amounts of data to the server.  Originally, I was going to use the low level socket connection, but am changing to HTTP and will use cURL to have these devices make a HTTP request to 192.168.1.200:1337.


<?php
require 'vendor/autoload.php';
use React\EventLoop\Factory;
use React\Http\Server as HttpServer;
use React\Socket\Server as SocketServer;


set_time_limit(0);


$loop = Factory::create();


$http_socket1 = new SocketServer($loop);
$http1 = new HttpServer($http_socket1);
$http1->on('request', function ($request, $response) {
    $response->writeHead(200, array('Content-Type' => 'text/plain'));
    $query = $request->getQuery();
    echo '127.0.0.1' . PHP_EOL;
    echo print_r($query,1) . PHP_EOL;
    $response->end(print_r($query,1));
});
$http_socket1->listen('1337', '127.0.0.1');


$http_socket2 = new SocketServer($loop);
$http2 = new HttpServer($http_socket2);
$http2->on('request', function ($request, $response) {
    $response->writeHead(200, array('Content-Type' => 'text/plain'));
    $query = $request->getQuery();
    echo '192.168.1.200' . PHP_EOL;
    echo print_r($query,1) . PHP_EOL;
    $response->end(print_r($query,1));
});
$http_socket2->listen('1337', '192.168.1.200');


$loop->run();
 

If both of those HTTP servers do the same thing there's no need to create two, just have one that listens on all addresses (unless you have a reason to limit the IPs).

 

$http_socket1 = new SocketServer($loop);
$http1 = new HttpServer($http_socket1);
$http1->on('request', function ($request, $response) {
    $response->writeHead(200, array('Content-Type' => 'text/plain'));
    $query = $request->getQuery();
    echo print_r($query,1) . PHP_EOL;
    $response->end(print_r($query,1));
});
$http_socket1->listen('1337', '0.0.0.0');
If they do different things then I'd use different port numbers. While there's nothing to technically stop you from using the same port but different IP's it will be confusing and likely lead to trouble down the road.

Did the part abou getting content from one instance to another make any sense?

Not really, which is why I was unsure if the two servers did the same thing or not.

 

My understanding of what you wrote is you have Apache on port 80 and your custom server on port 1337. Scripts running via apache need to connect to your server to pass it some data. You also have some other external client scripts that need to connect to the server and send/receive data.

 

It sounds like somewhere where a single server socket (on say 192.168.1.200:1337) would work, but two in order to easily distinguish between your apache clients and custom clients would also work fine.

Hi Kicken,  Does the following help?

 

Web client needs to send data to machine client.  It does so by sending data to web application which then cURLs it to a HTTP server which is tightly coupled to a socket server which is connected to the socket client. This seems a little excessive, but I don't know what would be better.  Maybe a Redis queue?

 

Also, the machine client needs to periodically send a lot of data to the server.  Originally, I planned on just using the low-level sockets connection, but this post https://forums.phpfreaks.com/topic/302824-help-with-sockets-and-reactphp/ made me change my mind.

 

Thanks

 

 

Capture.png

I think the question here is whether "machine client" and "server" have to be separate; both running on the same server would greatly simplify the architecture.

 

Yes, it would greatly simplify the architecture, however, the are separate remote machines.

I feel like your two machine client processed should be able to be combined as well as your two separate http servers which handle them. That would simplify things. Perhaps there is some reason for them being separate but from what I can recall of previous threads I don't see it.

 

I'd think a setup something more like this could work.

post-124404-0-35282500-1483209865.png

 

Your application server consists of two services.

- Apache: Handles your normal web traffic and browsers. Scripts run here can use cURL to communicate with the PHP Server

- PHP Server: Handles your remote client communications

 

Your remote clients consist of a single service:

- PHP Client: Handles your bi-directional communication needs. Has a periodic timer that does whatever your 1-minute cron task does.

 

 

 

HTTP May not work for your bi-directional needs however, at least not using any pre-written library. The problem is you'd need to alternate which side is the server vs the client based on which side needs to initiate communication. To send data to the application server you'd have: HTTP Client(Remote client) ---> HTTP Server(Application server) where as to send data to the remote client you'd have HTTP Server(Remote client) <--- HTTP Client(Application server). You could stick with the two socket interface with say port 1337 being Remote Client ---> Application Server and 1338 being Remote Client <--- Application Server

 

The JSON documents idea from the other thread would work fine with a single socket. You could just do something simple like each line is a json document and examine some field in that json to determine what to do. I'll code up a small example later.

post-124404-0-35282500-1483209865_thumb.png

Thanks Kicken,  It does seem like I can and should combine the clients and servers.  The only reason I was thinking of not doing so is to use HTTP when possible and otherwise using some low level sockets.  Let me more review your commends and think it over.  Thanks

  • Solution

I'll code up a small example later.

Here's that example. To try and simulate your bi-direction traffic plus having a timed job I coded up a little Red-light/Green-light system. The server accepts clients and sends them random red or green light messages. When a client sees a green-light it fakes moving and stops when it gets a red-light. Periodically it also sends the server how far it's moved and it's name. The server periodically lists the players and their distance. There is pretty much no error handling (such as for disconnects) in the code, I'll leave that as an exercise to the reader.

 

JSONStream.php - Sends and receives json documents via a socket stream.

<?php
namespace Kicken\RLGL;

use Evenement\EventEmitterInterface;
use Evenement\EventEmitterTrait;
use React\Stream\DuplexStreamInterface;

class JSONStream implements EventEmitterInterface {
    use EventEmitterTrait;

    private $socket;
    private $buffer;

    public function __construct(DuplexStreamInterface $socket){
        $this->socket = $socket;
        $this->buffer = '';

        $this->socket->on('data', function($data){
            $this->buffer .= $data;
            $this->parseBuffer();
        });
    }

    public function send($structure){
        $json = json_encode($structure);
        $this->socket->write($json."\r\n");
    }

    private function parseBuffer(){
        $eol = strpos($this->buffer, "\r\n");
        while ($eol !== false){
            $json = substr($this->buffer, 0, $eol);
            $this->buffer = substr($this->buffer, $eol + 2);
            $data = json_decode($json, true);

            if (json_last_error() == JSON_ERROR_NONE){
                $this->emit('data', [$data]);
            }

            $eol = strpos($this->buffer, "\r\n");
        }
    }
}
server.php - Short script to act as the server. Listens on port 1337 for connections and listens for info messages from each client. Sends light messages periodically.

 

<?php
require 'vendor/autoload.php';
require 'JSONStream.php';

$port = isset($argv[1])?$argv[1]:1337;
$clientList = new SplObjectStorage();

$loop = new \React\EventLoop\StreamSelectLoop();
$socket = new React\Socket\Server($loop);
$socket->on('connection', function (\React\Socket\ConnectionInterface $client) use (&$clientList){
    $client = new \Kicken\RLGL\JSONStream($client);
    $clientList->attach($client, []);

    $client->on('data', function($data) use (&$clientList, $client){
        if ($data['message'] == 'info'){
            $clientList[$client] = $data['info'];
        }
    });

    echo "New connection accepted.\r\n";
});

$loop->addPeriodicTimer(5, function () use ($clientList){
    $color = mt_rand(1,2) == 1?'red':'green';

    echo "Sending {$color} light.\r\n";
    /** @var \Kicken\RLGL\JSONStream $client */
    foreach ($clientList as $client){
        $client->send([
            'message' => 'light'
            , 'color' => $color
        ]);
    }
});
$loop->addPeriodicTimer(60, function() use ($clientList){
    echo "Current results:\r\n";
    foreach ($clientList as $client){
        $info = $clientList[$client];
        if (!empty($info)){
            echo "{$info['name']} has travelled {$info['distance']} feet.\r\n";
        }
    }
});

$socket->listen($port, '0.0.0.0');
$loop->run();
client.php - Connects to the server and listens for light messages. Periodically tells the server how far it has travelled.

 

<?php

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

$server = isset($argv[1])?$argv[1]:'127.0.0.1';
$port = isset($argv[2])?$argv[2]:1337;

/** @var \Kicken\RLGL\JSONStream $client */
$client = null;
$clientInfo = [
    'name' => getRandomName()
    , 'speed' => getRandomSpeed()
    , 'traveled' => 0
    , 'moving' => false
    , 'movingStartTime' => null
];

$loop = new \React\EventLoop\StreamSelectLoop();
$socket = new \React\SocketClient\TcpConnector($loop);
$socket->create($server, $port)->then(function ($stream) use (&$client, &$clientInfo){
    $client = new \Kicken\RLGL\JSONStream($stream);
    sendClientInfo();

    $client->on('data', function ($data) use (&$clientInfo){
        if ($data['message'] == 'light'){
            if ($data['color'] == 'green' && !$clientInfo['moving']){
                $clientInfo['moving'] = true;
                $clientInfo['movingStartTime'] = time();
                echo "Received green light!\r\n";
            } else if ($data['color'] == 'red' && $clientInfo['moving']){
                $movingTime = time() - $clientInfo['movingStartTime'];
                $distance = $movingTime * $clientInfo['speed'];
                $clientInfo['traveled'] += $distance;
                $clientInfo['moving'] = false;
                $clientInfo['movingStartTime'] = null;
                echo "Received Red light! Total distance = {$distance} feet.\r\n";
            }
        }
    });
});

$loop->addPeriodicTimer(15, 'sendClientInfo');

$loop->run();

function sendClientInfo(){
    global $client, $clientInfo;
    $infoToSend = [
        'name' => $clientInfo['name']
        , 'distance' => $clientInfo['traveled']
    ];

    echo "Updating server with data.\r\n";
    $client->send(['message' => 'info', 'info' => $infoToSend]);
}

function getRandomName(){
    static $names = ['Edmundo', 'Roxane', 'Evelynn', 'Isaias', 'Buena', 'Evan', 'Katharina', 'Darnell', 'Sharyl', 'Malka', 'Sharla', 'Delena', 'Leah', 'Marnie', 'Tammi', 'Joanna', 'Marva', 'Karyn', 'Kristal', 'Jayson'];
    shuffle($names);

    return $names[0];
}

function getRandomSpeed(){
    return mt_rand(1, 100) / 100;
}

Thank you Kicken!

 

I haven't gone through it in detail yet, however, I do like the way you are parsing the JSON more than my approach described by https://forums.phpfreaks.com/topic/302843-parsing-newline-delimited-json/.

 

One initial snag.  Class React\SocketClient\TcpConnector is not found.  I have the socket-client directory, however, don't have the TcpConnector.php file in it.  Looking at https://github.com/reactphp/socket-client/tree/master/src, however, I see the file.   Do I also need to add  "react/socket-client" to the composer file?  My composer setup is shown below.

[Michael@devserver react]$ ls -l
total 44
drwxrwxr-x. 4 Michael Michael 4096 Nov 21 05:26 cache
drwxrwxr-x. 4 Michael Michael 4096 Nov 21 05:26 child-process
drwxrwxr-x. 4 Michael Michael 4096 Nov 21 05:26 dns
drwxrwxr-x. 4 Michael Michael 4096 Nov 21 05:26 event-loop
drwxrwxr-x. 5 Michael Michael 4096 Nov 21 05:26 http
drwxrwxr-x. 5 Michael Michael 4096 Dec 28 06:09 http-client
drwxrwxr-x. 4 Michael Michael 4096 Dec 28 06:08 promise
drwxrwxr-x. 7 Michael Michael 4096 Nov 21 05:26 react
drwxrwxr-x. 5 Michael Michael 4096 Dec 28 06:08 socket
drwxrwxr-x. 4 Michael Michael 4096 Dec 28 06:09 socket-client
drwxrwxr-x. 5 Michael Michael 4096 Nov 21 05:26 stream
[Michael@devserver react]$ ls socket-client -l
total 28
-rw-rw-r--. 1 Michael Michael 1829 Dec  6 02:54 CHANGELOG.md
-rw-rw-r--. 1 Michael Michael  545 Dec  6 02:54 composer.json
-rw-rw-r--. 1 Michael Michael 1069 Dec  6 02:54 LICENSE
-rw-rw-r--. 1 Michael Michael  666 Dec  6 02:54 phpunit.xml.dist
-rw-rw-r--. 1 Michael Michael 3171 Dec  6 02:54 README.md
drwxrwxr-x. 2 Michael Michael 4096 Dec  6 02:54 src
drwxrwxr-x. 2 Michael Michael 4096 Dec  6 02:54 tests
[Michael@devserver react]$ ls socket-client/src -l
total 28
-rw-rw-r--. 1 Michael Michael   94 Dec  6 02:54 ConnectionException.php
-rw-rw-r--. 1 Michael Michael  113 Dec  6 02:54 ConnectorInterface.php
-rw-rw-r--. 1 Michael Michael 2811 Dec  6 02:54 Connector.php
-rw-rw-r--. 1 Michael Michael 1529 Dec  6 02:54 SecureConnector.php
-rw-rw-r--. 1 Michael Michael 2185 Dec  6 02:54 SecureStream.php
-rw-rw-r--. 1 Michael Michael 3605 Dec  6 02:54 StreamEncryption.php
-rw-rw-r--. 1 Michael Michael  875 Dec  6 02:54 UnixConnector.php
[Michael@devserver react]$
{
    "require": {
        "react/react": "^0.4.2",
        "vlucas/phpdotenv": "^2.4",
        "monolog/monolog": "^1.19",
        "slim/slim": "^3.4",
        "slim/twig-view": "^2.1"
    },
    "autoload": {
        "psr-4": {
            "MyServer\\": "src/"
        },
        "files": [
            "src/Support/helpers.php"
        ]


    }
}

 

 

[Michael@devserver datalogger]$ composer require react/socket-client:^0.5.3
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.


  Problem 1
    - react/react v0.4.2 requires react/socket-client 0.4.* -> satisfiable by react/socket-client[0.4.x-dev, v0.4.0, v0.4.1, v0.4.2, v0.4.3, v0.4.4, v0.4.5, v0.4.6] but these conflict with your requirements or minimum-stability.
    - react/react v0.4.2 requires react/socket-client 0.4.* -> satisfiable by react/socket-client[0.4.x-dev, v0.4.0, v0.4.1, v0.4.2, v0.4.3, v0.4.4, v0.4.5, v0.4.6] but these conflict with your requirements or minimum-stability.
    - react/react v0.4.2 requires react/socket-client 0.4.* -> satisfiable by react/socket-client[0.4.x-dev, v0.4.0, v0.4.1, v0.4.2, v0.4.3, v0.4.4, v0.4.5, v0.4.6] but these conflict with your requirements or minimum-stability.
    - Installation request for react/react ^0.4.2 -> satisfiable by react/react[v0.4.2].




Installation failed, reverting ./composer.json to its original content.
[Michael@devserver datalogger]$

Edited by NotionCommotion

Using composer, I was able to remove react, then add socket-client:^0.5.3.  Can't now add "react/react": "^0.4.2" back.  Don't know if it will cause any issues.

 

Thank you for the sample script.  It really helps.  A couple of questions:

 

Is there any difference between these two lines?  
  
$loop = new \React\EventLoop\StreamSelectLoop();
$loop = React\EventLoop\Factory::create();
Could you shed some light on this line.  Also, why is $client defined outside of it? 
$socket->create($server, $port)->then(function ($stream) use (&$client, &$clientInfo){});

 

Using composer, I was able to remove react, then add socket-client:^0.5.3.  Can't now add "react/react": "^0.4.2" back.  Don't know if it will cause any issues.

react/react is older and not really intended to be used anymore, instead you're supposed to just include the individual libraries as needed. My composer requirements for the example were:

    "require": {
        "react/socket": "^0.4.4",
        "react/stream": "^0.4.5",
        "react/event-loop": "^0.4.2",
        "react/socket-client": "^0.5.3"
    }
 

Is there any difference between these two lines?

Using the factory is probably better in general. The factory will look for the best event loop implementation your setup can support.

 

 

Also, why is $client defined outside of it?

So I can also use it in the sendClientInfo function later on. In reality it'd be better to create some classes for the client and server so that state like the connection and client information can be tracked as member variables.

react/react is older and not really intended to be used anymore, instead you're supposed to just include the individual libraries as needed. My composer requirements for the example were:

Thanks.  Just curious, how do you know this?  I haven't found too much documentation.

 

 

I am focusing on the client (not yet tested) part at first, and have a couple of questions:

  1. Does it make sense to use a class for client as I have done so?
  2. If the server is not started when the client is started, send() will result in an error.  Also, if the server had first been started, but then stopped, I don't think it will reconnect automatically.  My plan is to utilize another loop to check the connection, and if not connected, reconnect.  Am I doing this correctly?  Also,upon connection close, do I need to take additional actions?
  3. How can I modify send() so that the buffer will never be exceeded?  I expect I will need drain.  Can it be done without becoming blocking?
  4. The application (code not posted) needs to be able to change the cron addPeriodicTimer period and also needs to be able to send data.  To do so, I pass client to the app within clients constructor.  This doesn't seem quite right, but I don't know what else to do.  Thoughts?

 

Thanks!

<?php


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


use MyServer\Client;
use MyServer\ClientApp;


$logger = new \Monolog\Logger('my_logger');
$logger->pushHandler(new \Monolog\Handler\StreamHandler(__DIR__."/logs/client.log"));
$logger->addInfo('Server started');


$db = new \PDO("sqlite:".__DIR__."/db/datalogger.db");
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$db->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);


$client=new Client(new ClientApp($db, $logger));
$client->start();
<?php


namespace MyServer;


use React\EventLoop\Factory;
use React\SocketClient\TcpConnector;


class Client
{
    private $app,       //The main application
    $host, $port,       //The IP and port of the remote server
    $loop,              //The main loop
    $cron,              //The main work timer.  Can be changed by $app
    $connection=false;  //The sockets connection 


    public function __construct($app, $host, $port)
    {
        $this->app = $app;
        /*
        The main application needs to be able to send data and change the main addPeriodicTimer period.
        I Don't really like how I am doing this, but don't know how else, and ideally I would just give access to these two methods.
        */
        $this->app->client=$this;
    }


    public function start() {
        $this->loop = Factory::create();
        $socket = new TcpConnector($this->loop);
        $this->loop->addPeriodicTimer(1, function() {
            if(!$this->connection) {
                $socket->create($this->app->config->host, $this->app->config->port)->then(function ($stream) {
                    $this->connection = new \Kicken\RLGL\JSONStream($stream);
                    $this->connection->send($this->app->identifyCommand());   //Sends clients identity to server
                    $this->connection->on('data', function ($data) {
                        $this->app->process($data);
                    });
                    $this->connection->on('close', function() {
                        $this->connection = false;
                        //Do I need to destroy the socket, etc?
                    });
                });
            }
        });


        $this->cron=$this->loop->addPeriodicTimer($this->app->getCronTimer(), function(){
            $this->client->doCron();
        });


        $this->loop->run();
    }


    public function changeTimer($period)
    {
        $this->loop->cancelTimer($this->cron);
        $this->cron = $this->loop->addPeriodicTimer($period, function(){
            $this->client->cron();
        });        
    }


    public function send($data)
    {
        if($this->connection) {
            //How is drain handled to ensure that $data doesn't exceed buffer?
            $this->connection->send($data);
        }
        return $this->connection;
    }
}

 

Thanks.  Just curious, how do you know this?  I haven't found too much documentation.

Their notice about it being split into components and the fact that the main repository has not had any significant updates in a long time provides a strong hint. If you dig into the the issues area you'd also find an issue named Mark react/react as abondoned in order to redirect people to new components.

 

  • If the server is not started when the client is started, send() will result in an error.  Also, if the server had first been started, but then stopped, I don't think it will reconnect automatically.  My plan is to utilize another loop to check the connection, and if not connected, reconnect.  Am I doing this correctly?  Also,upon connection close, do I need to take additional actions?
Wrap your connection code into a simple connect() method. You can then monitor the socket for a disconnect and simple call the connect() method again to reconnect if desired. There shouldn't be any need to clean up any of the socket objects or what not. PHP will take care of the memory management and the socket will already have been closed.

 

To handle an error connecting to the server you can use the otherwise method on the promise. You'll also likely want to use a TimeoutConnector so you can control timeout.

 

Also note that my JSONStream doesn't forward events, it only emits it's own data event. To monitor the close event you'd have to either modify the class to forward it or watch the underlying stream object.

 

class Client {
    //...

    public function start(){
        $this->loop = Factory::create();
        $this->connect();
        $this->loop->run();
    }

    private function connect(){
        $socket = new TimeoutConnector(new TcpConnector($this->loop), 10, $this->loop);
        $socket->create($this->app->config->host, $this->app->config->port)->then(function($stream){
            $this->connection = new \Kicken\RLGL\JSONStream($stream);
            $this->connection->send($this->app->identifyCommand());   //Sends clients identity to server
            $this->connection->on('data', function($data){
                $this->app->process($data);
            });
            $stream->on('close', function(){
				$this->connection = null;
                //Determine whether or not to reconnect
                //call $this->connect(); if you want to reconnect
            });
        })->otherwise(function($reason){
            //Handle connection error
            //call $this->connect() to try again
        });
    }
}

 

  • How can I modify send() so that the buffer will never be exceeded?  I expect I will need drain.  Can it be done without becoming blocking?

 

You'd just have to implement your own buffering on top of it's buffering. I probably wouldn't really bother though since their buffer limit is implemented more as a suggestion rather than a hard limit. Their buffer class will accept whatever data you throw at it but begins returning false after 64k as hint that maybe you should wait a bit before sending more.

 

If you want to protected against them possibly changing their code to make it a hard limit then you'd just change send to append data to a variable and another variable to track whether the socket buffer is full or not. Add a listener for the drain event and if you have any data in your buffer try to write it and update the buffer full variable. You can look at their buffer class as an example, you'd be doing basically the same thing but without a limit.

 

 

 

  • The application (code not posted) needs to be able to change the cron addPeriodicTimer period and also needs to be able to send data.  To do so, I pass client to the app within clients constructor.  This doesn't seem quite right, but I don't know what else to do.  Thoughts?

 

You could create some kind of adjustable timer class that handles re-registering a timer and use that from within your application class. For example

class AdjustableTimer {
    private $loop;
    private $interval;
    private $callback;
    private $timer;

    public function __construct(LoopInterface $loop, $interval, callable $callback){
        $this->loop = $loop;
        $this->interval = $interval;
        $this->callback = $callback;
        $this->start();
    }

    public function setInterval($interval){
        $this->interval = $interval;
        $this->start();
    }

    public function stop(){
        $this->loop->cancelTimer($this->timer);
        $this->timer = null;
    }

    public function start(){
        if ($this->timer){
            $this->stop();
        }

        $this->timer = $this->loop->addPeriodicTimer($this->interval, $this->callback);
    }
}
Add a method to your client that will construct a variable timer and return it.

class Client {
    //...

    public function createAdjustableTimer($interval, $callback){
        return new AdjustableTimer($this->loop, $interval, $callback);
    }
}
  • Like 1

Thanks again. So, TimeoutConnector just closes a connection if not made within a given time frame.  If I ran the following without a connection, it would echo "otherwise" continuously.  That is to be expected, right?

 

$socket = new TimeoutConnector(new TcpConnector($this->loop), 10, $this->loop);
$socket->create($this->app->config->host, $this->app->config->port)->then(function($stream){
    // connection succeeded within 10.0 seconds
})->otherwise(function($reason){
    // Over 10 seconds or reasons do to TcpConnector()->create() 
    echo "otherwise" . PHP_EOL;
    $this->connect();
});
### Connection timeouts
 
The `TimeoutConnector` class implements the [`ConnectorInterface`](#connectorinterface) and allows you to add timeout handling to any existing connector instance.
 
It does so by decorating any given [`ConnectorInterface`](#connectorinterface) instance and starting a timer that will automatically reject and abort any underlying connection attempt if it takes too long.
 
```php
$timeoutConnector = new React\SocketClient\TimeoutConnector($connector, 3.0, $loop);
 
$timeoutConnector->create('google.com', 80)->then(function (React\Stream\Stream $stream) {
    // connection succeeded within 3.0 seconds
});

 

 

In regards to AdjustableTimer, I would still need to pass Client to ClientApp, right?

If I ran the following without a connection, it would echo "otherwise" continuously.  That is to be expected, right?

Yep.

 

In regards to AdjustableTimer, I would still need to pass Client to ClientApp, right?

Yep, you'd still have to be able to call the createAdjustableTimer method on the client.

$this->timer = $this->client->createAdjustableTimer(60, function(){
    echo "Cron";
});

//...
$this->timer->setInterval(10);
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.