Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connection refused #94

Closed
anditsung opened this issue Jun 23, 2021 · 6 comments
Closed

connection refused #94

anditsung opened this issue Jun 23, 2021 · 6 comments

Comments

@anditsung
Copy link

anditsung commented Jun 23, 2021

hi, i dont really know if this an issue or not

i try to read the register from address 1 to 65 it was working fine
but then i add to read register for 2001 till 2016 it will have connection refused error

i have try to read address 1 and 2001 only and have the same error
but after i remove the 2001 everything working fine

i try to read only from 2001 to 2016 it was working fine

the problem only occur when i combine both address

===

seems the problem only occur if when the address is to big
i try to read 100 and 200 working fine
then read 100, 200 and 300 will return connection refused
but if i read 200 and 300 working fine again

@anditsung
Copy link
Author

anditsung commented Jun 24, 2021

try {
foreach ($requests as $indexOrKey => $request) {
$uri = mb_strtolower($request->getUri());
$packet = $request->getRequest();
$connection = BinaryStreamConnection::getBuilder()
->setFromOptions(array_merge($options, ['uri' => $uri]))
->build();
$connections[] = $connection->connect();
$connection->send($packet);
$readStreams[$indexOrKey] = $connection->getStream();
}
$logger = $options['logger'] ?? null;
$readTimeoutSec = $options['readTimeoutSec'] ?? null;
$responsePackets = $this->receiveFrom($readStreams, $readTimeoutSec, $logger);
// extract values and match them old indexes as function argument had to maintain reliable 'order'
$result = [];
foreach ($responsePackets as $indexOrKey => $data) {
$readRequest = $requests[$indexOrKey];
$response = $readRequest->parse($data);
if ($throwOnError && $response instanceof ErrorResponse) {
throw new ModbusException('sendRequests resulted with modbus error. msg: ' . $response->getErrorMessage());
}
$result[$indexOrKey] = $response;
}
} finally {
// try to clean up
foreach ($connections as $connection) {
$connection->close();
}
}

seems the issue was here. if the connection was too fast it will return connection refused

i try to add sleep(1); after line 132 everything was working. but i dont think this is the perfect solution

@anditsung
Copy link
Author

anditsung commented Jun 24, 2021

foreach ($requests as $indexOrKey => $request) {
                $uri = mb_strtolower($request->getUri());
                $packet = $request->getRequest();
                $connection = BinaryStreamConnection::getBuilder()
                    ->setFromOptions(array_merge($options, ['uri' => $uri]))
                    ->build();
                $connections[] = $connection->connect();

                $responsePackets[$indexOrKey] = $connection->sendAndReceive($packet);
            }

i try something like this. and i dont have any error at all
can create a PR for this?

@aldas
Copy link
Owner

aldas commented Jun 24, 2021

How many requests are you sending in parallel? I assume you are using examples/example_parallel_requests.php based code?

If you use sendAndReceive you are changing NonBlockingClient nature to be serial. Same goes with using long sleeps with NonBlockingClient. Sending requests serially could be right for your situation - It could be that your device does not handle parallel requests well.

If doing serially is OK you could just make little helper function to send requests like that:

function sendsRequests(array $requests): array
{
    $connection = BinaryStreamConnection::getBuilder()
        ->setPort('5022')
        ->setHost('127.0.0.1') // we assume that port and ip is not different over requests
        ->setConnectTimeoutSec(1.5) // timeout when establishing connection to the server
        ->setWriteTimeoutSec(0.5) // timeout when writing/sending packet to the server
        ->setReadTimeoutSec(1.0) // timeout when waiting response from server
        ->build();

    try {
        $connection->connect();

        $results = [];
        foreach ($requests as $index => $request) {
            $binaryData = $connection->sendAndReceive($request->getRequest()); // send/receive request serially
            $response = $request->parse($binaryData);

            if ($response instanceof ErrorResponse) {
                throw new ModbusException('sendRequests resulted with modbus error. msg: ' . $response->getErrorMessage());
            }
            $result[$index] = $response;
        }
        $result = new ResultContainer($results, []);
        return $result->getData(); // extract data to assoc array
    } finally {
        $connection->close();
    }
}

$requests = ReadRegistersBuilder::newReadHoldingRegisters('tcp:https://127.0.0.1:5022')
    ->bit(256, 15, 'pump2_feedbackalarm_do')
    // will be split into 2 requests as 1 request can return only range of 124 registers max
    ->int16(657, 'battery3_voltage_wo')
    ->build(); // returns array of 2 requests

print_r(sendsRequests($requests));

@anditsung
Copy link
Author

wow... it was working
thank you very much..
im using deltaww HMI
some of the address have big different
there is 1 till 65
then there is $M1 address that will read as 2001 till 2016
using your method will read any address without the problem
except the result is not merge together
Screen Shot 2021-06-25 at 09 37 41

@aldas
Copy link
Owner

aldas commented Jun 25, 2021

probably changing return to would help

return array_merge(...$result->getData()); 

@anditsung
Copy link
Author

im doing something like this

$result = new ResultContainer($results, []);
            return collect($result->getData())->flatMap( function ($row) {
                return $row;
            });```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants