skip to Main Content

(linux, nginx)

Im using ajax go get info from /dev/ttyUSB0 serial port

@fgets() is reading port until result !BUT! if the AJAX receives a 504 error from NGINX then the stream does not terminate properly via fclose func. Can i set time out for fgets? i tried stream_set_timeout() but that command doing something i dont need (i think so because after 9 seconds stream doesnt terminate and when i start ajax next time i can see the effect of this issue).

and if i get 504 error 5 times in a row and when i try to scan card next time i need like 4-5 scans to finally get a result. Looks like fgets is moving pointer to the next line each time i call him. Can you help me to resolve this problems?

(if i try to set ajax timeout to 0 or 999999 i keep getting 504 after some time)

code from ajax_port_check.php

$device = '/dev/ttyUSB0';
$open_mode = 'r';

$handle = @fopen($device, $open_mode);
if ($handle) {
    stream_set_timeout($handle, 9);
    $data = @fgets($handle);
    @fclose($handle);
    $response = [
        'code' => 200,
        'status' => 'ok',
        'message' => 'Card successfully read',
        'content' => $data,
        'stream' => $handle . '',
    ];
} else {
    $response = [
        'code' => 403,
        'status' => 'error',
        'message' => 'File not fount / Access denied',
    ];
}
exit(json_encode($response));

main page with ajax

function scan_card(seconds) {
            var timer = startTimeout(seconds);
            $.ajax({
                url: "ajax_port_check.php",
                type: "post",
                success: function (response) {
                    response = JSON.parse(response);
                    console.log(response['content']);
                    stopTimeout(timer);
                },
                error: function () {
                    console.log('error');
                    stopTimeout(timer);
                },
                timeout: seconds * 1000
            });
        }

2

Answers


  1. Chosen as BEST ANSWER

    i have solve the problem)

    if i get "timed out error" im sending to file any string with PHP_EOL at the end (i used another ajax to send message "No card" . PHP_EOL). And next fopen and fgets will give me result i need

    code

    <?php
    $device = '/dev/ttyUSB0';
    $open_mode = 'r+';
    
    $handle = @fopen($device, $open_mode);
    if ($handle) {
        $data = @fwrite($handle, 'No card' . PHP_EOL);
        @fclose($handle);
    }
    ?>
    

  2. Your stream_set_timeout call is mostly likely failing and returning zero, meaning no timeout is established. The docs don’t explicitly say so, but it appears this function is intended for socket resources and has no effect on file handles.

    Using non-blocking I/O would probably solve your problem here, which can be enabled using stream_set_blocking($handle, false). This will cause the fgets call to return any available data immediately, or false if nothing is available at call time.

    If you want to wait a moment for data to show up, you’ll need to add your own timeout:

    // Make the file handle non-blocking
    stream_set_blocking($handle, false);
    
    $start = microtime(true);
    $timeoutSecs = 5.0;
    
    while (microtime(true) - $start < $timeoutSecs) {
    
        // Try to read from the file handle (non-blocking)
        $data = fgets($handle);
        if ($data !== false) {
            break;
        }
    
        // No data available yet - wait 10 milliseconds
        usleep(10000);
    }
    
    if ($data === false) {
        // No data could be read before the timeout elapsed
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search