분류 php

실시간 애플리케이션을 위한 Ratchet을 사용하여 PHP에서 WebSocket 서버를 생성하는 방법

컨텐츠 정보

  • 조회 1,252 (작성일 )

본문

Build a PHP WebSocket Server 


WebSockets에 대해 논의 할 때, PHP는 기본 지원이 없기 때문에 대화에 거의 포함되지 않습니다. 또한 PHP가 정상적으로 실행되는 HTTP 서버인 Apache는 지속적인 연결을 염두에 두고 구축되지 않으므로 타사 라이브러리에 구현 책임이 있습니다.


https://www.twilio.com/blog/create-php-websocket-server-build-real-time-even-driven-application 


PHP를 "실시간"개발에 대한 토론으로 가져 오려는 많은 시도가 있었지만 대부분은 Ratchet project와 비교할 때 창백해졌습니다. 클라이언트와 서버간에 실시간 양방향 메시지를 제공하기 위한 PHP WebSocket 라이브러리.


이 튜토리얼에서는 PHP와 함께 Ratchet을 사용하여 HTML 양식에서 보낸 메시지를 실시간으로 처리하는 간단한 WebSocket 서버를 만드는 방법을 배웁니다. 이 양식에는 단일 <input>과 <button>이 표시되어 모든 클라이언트 브라우저에 메시지를 보냅니다. 사용자가 메시지를 보낼 때마다 메시지가 다른 화면에 실시간으로 표시됩니다.


이 샘플 응용 프로그램은 최신 채팅 응용 프로그램의 표준을 기반으로 구축되며 고유한 WebSocket 기반 응용 프로그램을 구축 할 수 있습니다.


WebSocket은 무엇입니까? 


웹 소켓은 서버와 하나 이상의 클라이언트 간의 지연 시간이 짧거나 빠른 지속적인 연결입니다. AJAX 요청과 달리 WebSockets는 양방향 (푸시 풀)이므로 클라이언트와 서버가 서로 실시간으로 듣고 변경 사항에 응답 할 수 있습니다.


이 자습서를 완료하는 데 필요한 도구 


이 학습서를 완료하려면 다음 전제 조건이 필요합니다.

  • 로컬로 설치된 PHP 7+
  • 응용 프로그램 종속성을 저장하기 위한 Composer
  • 클라이언트 쪽 응용 프로그램에 터널을 만들기 위한 ngrok

응용 프로그램 디렉토리 및 파일 작성 


터미널에서 다음 명령을 실행하여 프로젝트 디렉토리 및 모든 필수 파일을 생성하십시오.


$ mkdir php-sockets && cd php-sockets
$ touch composer.json index.html app.php
$ mkdir app && cd app && touch socket.php

프로젝트 루트 디렉토리로 다시 이동하십시오.


참고 : 앞으로 건너 뛰려면 여기에서 전체 소스 코드를 사용할 수 있습니다. 


Composer 프로젝트 설정 및 Ratchet 포함 


애플리케이션은 Composer를 사용하여 종속성을 관리하고 자동 로딩 기능을 제공합니다. 우리는 이미 Ratchet에 대한 의존성을 저장하는 데 필요한 composer.json 파일을 만들었습니다. 선호하는 IDE에서 파일을 열고 다음 코드를 추가하여 Ratchet을 포함하십시오.


{
    "autoload": {
        "psr-4": {
            "MyApp\\": "app"
        }
    },
    "require": {
        "cboden/ratchet": "^0.4"
    }
}

이 선언은 오토로더에 PSR-4 프로토콜을 사용하고 MyApp을 프로젝트 설정에서 생성 한 앱 폴더에 매핑 합니다. 이 네임 스페이스는 후속 단계에서 프로젝트 클래스를 포함하는 데 사용됩니다. 기본적으로 composer.json은 프로젝트에서 Ratchet 패키지를 지정하기 위해 require 키를 사용합니다.


composer.json이 설정되었으므로 실제로 종속성을 설치해야 합니다. 터미널에서 다음 명령을 실행하십시오. 프로젝트 루트 폴더 안에 있는지 확인하십시오.


$ composer install 


WebSocket 클래스 만들기 


이제 코드를 작성할 준비가 되었습니다! IDE로 돌아가서 app/socket.php를 엽니 다. 이 파일에는 WebSocket 서버에 대한 연결 처리 방법을 구현하는 데 필요한 클래스가 들어 있습니다. 아래와 같이 다음 코드를 붙여 넣습니다.


<?php

namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Socket implements MessageComponentInterface {

    public function __construct()
    {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {

        // Store the new connection in $this->clients
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {

        foreach ( $this->clients as $client ) {

            if ( $from->resourceId == $client->resourceId ) {
                continue;
            }

            $client->send( "Client $from->resourceId said $msg" );
        }
    }

    public function onClose(ConnectionInterface $conn) {
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
    }
}

MessageComponentInterface는 추상 클래스이므로 실제로 사용하는지 여부에 관계없이 onOpen, onMessage, onClose 및 onError의 네 가지 메소드를 모두 구현해야 합니다. 각 방법의 책임에 대한 간략한 요약은 다음과 같습니다.


onOpen-이 방법을 사용하면 서버에 새로 연결할 때 응답 할 수 있습니다. 연결 ID를 데이터베이스에 저장하거나 다른 서비스와 상호 참조하거나 클라이언트의 모음에 연결을 저장하는 데 사용할 수 있습니다.


onMessage-아마도 응용 프로그램에서 가장 중요한 부분 인이 방법은 실제로 서버로 전송 된 메시지 또는 데이터를 처리합니다. $msg를 캡처 하는 것 외에도 $from 매개 변수를 허용하므로 응용 프로그램이 연결된 클라이언트에 따라 수행 할 작업을 결정할 수 있습니다. 이 예에서는 각 메시지를 모든 고객에게 실시간으로 보내는 것입니다. 또한 메시지를 보낸 고객에게 메시지를 보내지 않도록 합니다.


onClose-이름에서 알 수 있듯이 클라이언트가 연결을 닫으면 이 메소드가 실행됩니다.


onError-이 메소드는 연결에 의해 오류가 발생하면 시작됩니다.


HTTP 서버 생성 


이제 서버로 들어오는 연결을 처리하는 데 필요한 모든 논리를 성공적으로 만들었습니다. 마지막으로 구현해야 할 부분은 포트 8080을 수신하는 HttpServer입니다. app.php 파일을 열고 다음 코드를 추가하십시오.


<?php

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Socket;

require dirname( __FILE__ ) . '/vendor/autoload.php';

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Socket()
        )
    ),
    8080
);

$server->run();

위에서 볼 수 있듯이 $server 객체는 Socket() 및 WebSocket 서버 WsServer에 의해 생성되고 포트 8080에 할당 된 HTTP 서버를 포함합니다. 이 파일은 서버를 활성화하기 위해 명령 줄에서 실행하는 것입니다.


클라이언트 응용 프로그램 만들기 


마지막으로 생성해야 할 항목은 실제 브라우저 응용 프로그램입니다. 이 간단한 페이지에는 키 입력을 캡처하여 WebSocket으로 보내는 <textarea>가 포함됩니다. 아래 코드를 보고 index.html에 붙여 넣습니다.


<html>
    <head>
        <style>
            input, button { padding: 10px; }
        </style>
    </head>
    <body>
        <input type="text" id="message" />
        <button onclick="transmitMessage()">Send</button>
        <script>
            // Create a new WebSocket.
            var socket  = new WebSocket('ws://localhost:8080');

            // Define the 
            var message = document.getElementById('message');

            function transmitMessage() {
                socket.send( message.value );
            }

            socket.onmessage = function(e) {
                alert( e.data );
            }
        </script>
    </body>
</html>

우리의 클라이언트 측 애플리케이션은 간단합니다. ws://localhost:8080에서 서버에 WebSocket 연결을 설정하고 "보내기"버튼을 누르면 메시지가 서버로 전송됩니다. 멋진 부분은 메시지가 수신 되면 메시지 내용이 포함 된 alert()을 사용하여 각 클라이언트에게 다시 브로드 캐스트 된다는 것입니다.


WebSocket 서버 테스트 


터미널에서 다음을 실행하여 WebSocket 서버를 시작하십시오.


$ php app.php 


별도의 터미널에서 ngrok를 실행하여 HTTP 서버를 인터넷에 노출하십시오.


$ ngrok http 80 


ngrok screen 


HTTPS 전달 주소를 복사하여 두 개의 별도 브라우저 창에 붙여 넣습니다. 각 입력에 메시지를 입력하고 "보내기"버튼을 누르십시오. 개별 창마다 경고가 트리거 됩니다.


Testing PHP Websocket.mov.gif 


추가 자료 


PHP WebSockets에 대한 자세한 내용은 Samuel Attard의“내가 원했던 PHP 웹 소켓에 대한 자습서”를 확인하십시오.


결론 


우리가 지은 것에 대해 매우 기대됩니다. 여러분도 그래야 합니다! 이 튜토리얼은 실제로 PHP에서 WebSocket을 구현할 수 있음을 증명합니다!


PHP에 대해 잘 알고 있다면 이 스크립트를 그대로 둘 수 없습니다. 연결이 종료되면 서버가 더 이상 존재하지 않습니다.


이 제한을 제거하기 위해 서비스를 작성하고 백그라운드에서 서버를 실행할 수 있습니다.