고성능 PHP 네트워크 서비스를 구축 할 때 전통적인 차단 소켓 통신 모드는 종종 높은 일환 시나리오의 요구를 충족시킬 수 없습니다. PHP 네트워크 애플리케이션의 응답 속도 및 처리량 기능을 더 잘 향상시키기 위해 Socket_accept ()를 사용하여 소셜 _set_nonblock ()을 사용하여 비 블로킹 통신을 달성하는 것은 실현 가능하고 효과적인 수단입니다. 이 기사는이 기술의 구현을 심도있게 설명하고 참조 할 수있는 예제 코드를 제공합니다.
기본적으로 PHP 소켓 통신이 차단됩니다. 즉, 프로그램이 Socket_Accept () 또는 Socket_read () 작업을 실행할 때 클라이언트 연결이나 데이터가 읽을 수없는 경우 프로그램이 대기합니다. 이 방법은 간단하지만 프로그램의 동시성 능력을 크게 제한합니다.
비 블로킹 커뮤니케이션을 통해 항상 기다리지 않고 클라이언트 연결이나 데이터없이 프로그램의 다른 부분을 계속 실행할 수 있습니다. 이 메커니즘은 많은 짧은 연결 또는 여러 클라이언트 요청이 동시에 수신되는 시나리오를 처리하는 데 매우 적합합니다.
socket_accept () : 클라이언트 연결을 수락하는 데 사용됩니다. 연결이 없으면 연결이 올 때까지 차단됩니다.
socket_set_nonblock () : 소켓을 비 블로킹 모드로 설정하여 socket_accept ()가 연결되지 않아 기본 스레드를 차단하지 않도록하십시오.
비 블로킹 모드에서는 incincoming 연결로 인해 전체 프로세스를 차단하지 않고 새로운 Connection 요청 루프 별 루프를들을 수 있습니다. Socket_select ()를 결합하여 여러 소켓 상태를 폴링하여 성능을 더욱 최적화 할 수 있습니다.
다음은 비 블로킹 소켓을 사용하는 간단한 PHP 서버의 예입니다.
<?php
$host = '0.0.0.0';
$port = 8080;
// 만들다socket
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($server === false) {
die("socket_create() failed: " . socket_strerror(socket_last_error()));
}
// 설정socket재사용 가능
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
// 바인드 포트
if (!socket_bind($server, $host, $port)) {
die("socket_bind() failed: " . socket_strerror(socket_last_error($server)));
}
// 감시 장치
if (!socket_listen($server, 5)) {
die("socket_listen() failed: " . socket_strerror(socket_last_error($server)));
}
// 설정为비 차단
socket_set_nonblock($server);
$clients = [];
echo "서버가 시작되었습니다,감시 장치端口 $port ...\n";
while (true) {
// 새로운 연결을 수락하십시오(비 차단)
$client = @socket_accept($server);
if ($client !== false) {
socket_set_nonblock($client);
$clients[] = $client;
echo "새로운 클라이언트 연결: " . count($clients) . " 총 연결 수\n";
}
// 클라이언트 데이터를 처리합니다
foreach ($clients as $key => $client) {
$data = @socket_read($client, 1024, PHP_NORMAL_READ);
if ($data === false) {
continue;
}
if ($data === "") {
// 클라이언트 단절
socket_close($client);
unset($clients[$key]);
echo "클라이언트 단절\n";
continue;
}
$data = trim($data);
if ($data) {
echo "수신 된 데이터: $data\n";
$response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from m66.net\r\n";
socket_write($client, $response);
socket_close($client);
unset($clients[$key]);
}
}
// 피하다CPU점유100%
usleep(100000);
}
socket_close($server);
?>
socket_set_nonblock ()을 사용하는 주요 장점은 다음과 같습니다.
주 스레드를 차단하지 않으므로 여러 연결이 동시에 처리 될 수 있습니다.
보다 복잡한 이벤트 루프를 구현하기 위해 socket_select () 와 같은 함수와 쉽게 결합 할 수 있습니다.
채팅방, 인스턴트 메시징, 웹 소켓 서버 등과 같은 높은 동시성 시나리오에서 성능을 향상시킬 수 있습니다.
비 블로킹 모드에서는 오류를 억제하기 위해 @를 사용하거나 socket_last_error ()를 판단하는 것과 같은 예외 처리에주의를 기울여야합니다.
코드 로직에서는 리소스 누출을 피하기 위해 연결의 수명주기를 적극적으로 관리해야합니다.
복잡한 동시성 제어를 위해서는 여러 프로세스 (예 : PCNTL_FORK () ) 또는 코 루틴 프레임 워크 (예 : Swoole)를 사용하는 것을 고려할 수 있습니다.
socket_accept () 와 socket_set_nonblock ()을 결합하면 PHP 네트워크 응용 프로그램의 동시성 성능 및 응답 속도를 효과적으로 향상시킬 수 있습니다. PHP는 네트워크 프로그래밍의 일부 기본 언어만큼 강력하지는 않지만 여전히 안정적이고 안정적인 네트워크 서비스 시스템을 합리적으로 구축 할 수 있습니다. 이 기사가 비 차단 커뮤니케이션 메커니즘과 그 실습을 이해하는 데 도움이되기를 바랍니다.