KTVCentral/app/Services/TcpSocketClient.php

70 lines
2.0 KiB
PHP
Raw Permalink Normal View History

<?php
namespace App\Services;
use Illuminate\Support\Facades\Log;
use Exception;
class TcpSocketClient
{
protected string $ip;
protected int $port;
protected int $timeout;
public function __construct(string $ip, int $port, int $timeout = 5)
{
$this->ip = $ip;
$this->port = $port;
$this->timeout = $timeout;
}
public function send(string $data, string $breakOn = "\n"): string
{
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
$err = socket_strerror(socket_last_error());
Log::error("Socket create failed: {$err}");
throw new Exception("Socket create failed: {$err}");
}
// 設定寫入超時(發送)
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, [
'sec' => $this->timeout,
'usec' => 0,
]);
// 設定讀取超時(接收)
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, [
'sec' => $this->timeout,
'usec' => 0,
]);
$result = socket_connect($socket, $this->ip, $this->port);
if ($result === false) {
$err = socket_strerror(socket_last_error($socket));
Log::error("Socket connect failed: {$err}");
throw new Exception("Socket connect failed: {$err}");
}
$write = socket_write($socket, $data, strlen($data));
if ($write === false) {
$err = socket_strerror(socket_last_error($socket));
Log::error("Socket write failed: {$err}");
throw new Exception("Socket write failed: {$err}");
}
$response = '';
while ($out = socket_read($socket, 2048)) {
$response .= $out;
if ($breakOn && strpos($response, $breakOn) !== false) {
break;
}
}
socket_close($socket);
if ($response === '') {
Log::warning('Socket read empty or timeout.');
}
return $response;
}
}