Closed anditsung closed 3 years ago
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
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?
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://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));
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
probably changing return to would help
return array_merge(...$result->getData());
im doing something like this
$result = new ResultContainer($results, []);
return collect($result->getData())->flatMap( function ($row) {
return $row;
});```
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