PHP를 사용하여 소켓 기반 서버 또는 클라이언트 프로그램을 구축 할 때 영구 연결은 매우 일반적인 요구 사항입니다. 특히 인스턴트 메시징, 온라인 게임 서버 또는 데이터 푸시와 같은 시나리오에서 소켓을 오랫동안 연결하고 끊임없이 늘어선 상태로 유지하는 것은 성능 및 사용자 경험에 큰 영향을 미칩니다.
이 시나리오에서 Socket_clear_error () 의 합리적인 사용은 연결을 안정적으로 유지하는 핵심 수단입니다. 이 기사는 사용 방법을 심층적으로 탐색하고 몇 가지 실제 예제를 결합하여 불분명 한 오류로 인해 연결 중단을 피하는 방법을 설명합니다.
Socket_clear_error () 는 PHP가 지정된 소켓과 관련된 오류 정보를 지우기 위해 제공하는 소켓 작동 함수입니다. 함수 서명은 다음과 같습니다.
void socket_clear_error ([ resource $socket ] )
특정 소켓 또는 전 세계에서 사용할 수 있습니다. 소켓 작업에서 오류가 발생하면 오류 메시지가 저장됩니다. 이러한 오류가 제 시간에 지워지지 않으면 다음에 소켓 함수가 호출되면 동작에 영향을 줄 수 있으며 연결이 연결이 끊어집니다.
긴 연결을 사용할 때 다음과 같은 연결을 끊는 데는 여러 가지 이유가 있습니다.
네트워크 지터;
클라이언트는 연결을 닫습니다.
서버 내부 처리 오류가 잡히지 않습니다.
오류 스태킹이 지워지지 않습니다.
마지막은 우리 기사의 초점입니다. 약간의 치명적이지 않은 오류 인 경우에도 Socket_clear_error () 를 통해 지우지 않으면 다음 번에 socket_write () 및 socket_read () 와 같은 다음 시간에 "오류 상태"가 감지되어 비정상적으로 반환하거나 인터럽트를 트리거 할 수 있습니다.
다음은 클라이언트 요청을 처리하고 긴 연결을 유지하는 일반적인 PHP 소켓 서버 측 코드 스 니펫입니다.
$host = '0.0.0.0';
$port = 9000;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, $host, $port);
socket_listen($socket);
$clients = [];
while (true) {
$read = $clients;
$read[] = $socket;
$write = $except = null;
socket_select($read, $write, $except, 0, 200000); // 비 차단
if (in_array($socket, $read)) {
$client = socket_accept($socket);
$clients[] = $client;
socket_clear_error($client); // 새 연결의 오류 상태를 지우십시오
}
foreach ($clients as $key => $client) {
$data = @socket_read($client, 1024, PHP_NORMAL_READ);
if ($data === false) {
$error = socket_last_error($client);
if ($error !== 0) {
echo "Socket error: " . socket_strerror($error) . "\n";
socket_clear_error($client);
}
continue;
}
$data = trim($data);
if ($data == 'quit') {
socket_close($client);
unset($clients[$key]);
continue;
}
$response = "Server received: $data\n";
@socket_write($client, $response, strlen($response));
socket_clear_error($client); // 각 커뮤니케이션 후 오류가 발생합니다
}
}
이 코드는 몇 가지 주요 전략을 보여줍니다.
클라이언트 연결이 수신 될 때마다 Socket_clear_error ()를 사용하여 즉시 상태를 지우십시오.
각 읽기 또는 쓰기 작업 후에 가능한 오류가 명확합니다.
치명적이지 않은 오류 (예 : 임시 네트워크 정전)의 경우 즉시 연결을 끊지 말고 처리하고 계속 처리하십시오.
오류를 지우는 것 외에도 합리적으로 "하트 비트 패키지"를 설계하는 것도 연결을 지속적으로 유지하는 열쇠입니다. 하트 비트 메커니즘을 통해 클라이언트는 고정 된 시간에 가벼운 데이터 패킷을 서버로 보낼 수 있습니다. 일정 기간 후에 심장 박동이 수신되지 않으면 연결을 자동으로 닫을 수 있습니다.
// 하트 비트 응답 예제의 단순화 된 버전
if ($data == 'ping') {
@socket_write($client, "pong\n");
socket_clear_error($client);
}
이것은 socket_clear_error () 와 "실제 부서진"과 "잘못 판단 줄"의 차이를 더 잘 감지 할 수 있습니다.
오류를 오랫동안 지우지 않으면 소위 "좀비 연결", 즉 소켓 객체가 여전히 존재하지만 이미 유효하지 않은 상태에 있습니다. 다음은 모든 고객의 상태를 정기적으로 확인하는 방법입니다.