>  기사  >  백엔드 개발  >  PHP 소켓에서 긴 연결을 구현하는 방법

PHP 소켓에서 긴 연결을 구현하는 방법

伊谢尔伦
伊谢尔伦원래의
2018-05-14 17:13:3825482검색

긴 연결이란 무엇입니까?

친구들은 온라인 채팅 도구와 웹 온라인 채팅 도구를 많이 봤을 것입니다. 학교에는 익숙한 기능이 있습니다. 누군가가 귀하에게 답장을 보내면 즉시 웹사이트에 메시지가 나타납니다. 현재 페이지를 새로 고치지 않은 경우 Gmail에도 이 기능이 있습니다. 웹페이지가 새로 고쳐진 적이 없더라도 웹사이트에서 즉시 알려줍니다. 말하자면, 링크를 재사용하여 데이터와 지속적으로 상호작용한다는 사실은 모두가 잘 알고 있을 것입니다. 오늘날 많은 인터넷 비즈니스 시나리오에서는 게임, 채팅, 정보 푸시 등과 같은 긴 연결의 지원이 필요합니다. 따라서 많은 유사한 기능이 긴 연결과 분리될 수 없습니다. 이전 장에서는 PHP 소켓 통신을 소개했습니다. 이번 장에서는 PHP 소켓 긴 연결을 소개합니다.

긴 연결 및 짧은 링크

짧은 연결은 일반적으로 단일 항목의 데이터를 클라이언트에 적극적으로 "푸시"할 수 없습니다. 연결 훨씬 더 나은 점은 백엔드와 프런트엔드 기술의 조합을 사용하여 서버의 "정보 푸시" 기능을 실현할 수 있다는 것입니다. 데이터베이스에 업데이트가 있으면 백엔드 프로그램이 즉시 데이터를 "푸시"할 수 있습니다. , 여러 번 반복적으로 요청하는 대신 연결이 여러 번 설정되고 연결이 끊어집니다.

아마도 다음과 같은 설명이 있을 것입니다.

  1. 소위 롱 커넥션(Long Connection)이란 SOCKET 연결이 이루어진 후 사용 여부에 관계없이 연결을 유지하는 것을 말하며, 그러나 보안이 좋지 않습니다. 소위 짧은 연결 연결은 SOCKET 연결을 설정하고 데이터를 보내고 받은 후 즉시 연결을 끊는 것을 말합니다. 일반적으로 은행에서는 짧은 연결을 사용합니다.

  2. 긴 연결을 의미합니다. 현재 데이터 전송 중인지 수신 중인지에 관계없이 TCP 기반 통신에서 연결을 유지합니다. 짧은 연결이란 데이터 전송이 있을 때만 연결이 이루어지고, 클라이언트-서버 통신/데이터 전송이 완료된 후에 연결이 종료되는 것을 의미합니다.

  3. 통신 방법
    각 네트워크 요소 사이에는 긴 연결과 짧은 연결의 두 가지 연결 방법이 있습니다. 소위 긴 연결은 TCP 연결을 유지하는 동안 여러 데이터 패킷이 지속적으로 전송될 수 있음을 의미합니다. 데이터 패킷이 전송되지 않으면 연결을 유지하기 위해 양쪽 당사자가 감지 패킷을 보내야 합니다. 짧은 연결은 통신 당사자가 데이터를 교환할 때 TCP 연결이 설정되는 것을 의미합니다. 즉, 각 TCP 연결은 한 쌍의 CMPP 메시지 전송만 완료합니다.
    이 단계에서는 ISMG는 반드시 장기 연결 통신 방식을 사용해야 하며, SP와 ISMG 간에는 장기 연결 통신 방식을 사용하는 것이 좋습니다.

  4. 짧은 연결: 예를 들어 http만 연결하고 요청하고 닫는 경우 처리 시간이 짧을 경우 서버가 종료될 수 있습니다. 연결. 긴 연결: CMPP와 같은 일부 서비스는 서버에 대한 장기간 연결이 필요하며 일반적으로 사용자가 온라인으로 유지 관리해야 합니다.

소켓 긴 연결 구현

PHP 스크립트에 액세스할 때마다 모든 PHP 스크립트가 실행될 때까지 기다립니다. 지속적으로 실행하기 위해 스크립트가 필요한 경우 작업 목적을 달성하려면 PHP 긴 연결을 사용해야 합니다.

긴 연결을 사용하려면 소켓 캡슐화를 처리해야 합니다. 다음은 긴 소켓 연결을 수행하는 코드입니다.

예제 코드는 다음과 같습니다.

<?php
$sfd = socket_create(AF_INET, SOCK_STREAM, 0);  
socket_bind($sfd, "0.0.0.0", 1234);  
socket_listen($sfd, 511);  
socket_set_option($sfd, SOL_SOCKET, SO_REUSEADDR, 1);  
socket_set_nonblock($sfd);  
$rfds = array($sfd);  
$wfds = array(); 
 
do{  
    $rs = $rfds;  
    $ws = $wfds;  
    $es = array();  
    $ret = socket_select($rs, $ws, $es, 3);        
    //读取事件 
    foreach($rs as $fd){  
        if($fd == $sfd){ 
           $cfd = socket_accept($sfd);  
           socket_set_nonblock($cfd);  
            $rfds[] = $cfd;  
            echo "new client coming, fd=$cfd\n";  
        }else{  
            $msg = socket_read($fd, 1024); 
 
            if($msg <= 0){  
                //close  
            }else{                 
                echo "on message, fd=$fd data=$msg\n";  
            }  
        }  
    } 
  
    //写入事件 
    foreach($ws as $fd){  
        socket_write($fd, ........);  
    }       
}while(true);
?>

다음은 효율성을 향상시킵니다.

<?php
$sfd = stream_socket_server (&#39;tcp://0.0.0.0:1234&#39;, $errno, $errstr);  
stream_set_blocking($sfd, 0);  
$base = event_base_new();  
$event = event_new();  
event_set($event, $sfd, EV_READ | EV_PERSIST, &#39;ev_accept&#39;, $base);  
event_base_set($event, $base);  
event_add($event);  
event_base_loop($base); 
 
function ev_accept($socket, $flag, $base)  
{  
    $connection = stream_socket_accept($socket);  
    stream_set_blocking($connection, 0);  
    $buffer = event_buffer_new($connection, &#39;ev_read&#39;, NULL, &#39;ev_error&#39;,  $connection);      
    event_buffer_base_set($buffer, $base);  
    event_buffer_timeout_set($buffer, 30, 30);  
    event_buffer_watermark_set($buffer, EV_READ, 0, 0xffffff);  
    event_buffer_priority_set($buffer, 10);  
    event_buffer_enable($buffer, EV_READ | EV_PERSIST);  
} 
 
function ev_error($buffer, $error, $connection)  
{  
    event_buffer_disable($buffer, EV_READ | EV_WRITE);                  
    event_buffer_free($buffer);                  
    fclose($connection);                  
} 
 
function ev_read($buffer, $connection)  
{  
    $read = event_buffer_read($buffer, 256);  
    //do something....  
}
?>

사람 수가 늘어나고 동시성이 증가함에 따라 단일 프로세스로는 더 이상 수요를 충족할 수 없습니다. 이 문제를 해결하기 위해 swoole, Workerman 등과 같은 기성 확장 및 라이브러리가 있습니까? 그런데 우리는 PHP를 사용하여 웹을 개발할 때 웹서버 관련 라이브러리를 개발에 사용하지 않죠? 우리는 단순한 메아리일 뿐입니다. 이런 복잡한 것들은 모두 nginx나 apache에 넘겨주고, 그들이 주저 없이 주도적으로 나서서 우리가 로직 작성에 집중할 수 있게 해준다. 소켓 서비스 작성은 웹 서비스 작성보다 더 발전된 것이 아닙니다. 모두 코딩 및 완료 요구사항입니다. 통신 계층은 고정되어 있지만 하나는 nginx에 의해 완료되고 다른 하나는 직접 완료됩니다. . 하지만 이제는 nginx+fpm, fooking+fpm=php 긴 연결과 유사한 솔루션을 사용하여 연결을 전달하고 라우터를 사용하여 메시지를 전달합니다.

코드는 다음과 같습니다.

<?php
$sid = $_SERVER[&#39;SESSIONID&#39;];//这是sessionid  
$data = file_get_contents("php://input");//这样就能拿到请求内容了  
//想要返回消息只需要两步  
header(&#39;Content-Length: 11&#39;);//返回给客户端字节数  
echo "hello world";  
//想要给别的用户发消息  
include &#39;api.php&#39;;  
$router = new RouterClient(&#39;router host&#39;, &#39;router port&#39;);  
$router->sendMsg(用户sessionid, "fuck you");  
//想要给所有人要消息  
$router->sendAllMsg("fuck all");  
//想给指定组发消息(类似redis的pub/sub)  
$router->publish("channel name", "fuck all");
?>

[관련 튜토리얼 권장 사항]

1. "php.cn Dugu Jiujian (4 ) -php 비디오 튜토리얼

2. PHP 프로그래밍 입문부터 숙달까지 튜토리얼 전체

위 내용은 PHP 소켓에서 긴 연결을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.