Home
home
🏡 홈
home

Ubuntu 22.04 Apache + PHP + Swoole 기반 WebSocket 환경 구축

분류
프로젝트
태그
Web
Server
Linux
C
Network
PHP
작성자
작성일
2025/04/14 00:40
실시간 채팅 기능을 PHP로 구현할 수 있을지에 대한 궁금증에서 출발하여,
WebSocket 서버 환경을 직접 구성하고 동작을 확인해본 내용을 정리하였습니다.

시작하게 된 배경입니다

최근 실시간 기능에 대한 관심이 생기면서, PHP로도 실시간 채팅을 구현할 수 있는지 알아보게 되었습니다.
조사 과정에서 PHP에서 WebSocket 서버를 실행할 수 있도록 도와주는 Swoole 확장을 알게 되었으며, 이를 통해 직접 환경을 구성하고 실행해보았습니다.
특히 Swoole은 C 언어로 개발된 PHP 확장으로, PHP로 작성된 기존의 WebSocket 라이브러리보다 훨씬 뛰어난 성능을 제공합니다.
네이티브 수준의 처리 속도와 낮은 메모리 소비 덕분에 실시간 통신 기능에 적합하다는 평가를 받고 있습니다.

Apache + PHP + 확장 모듈 설치입니다

다음 명령어를 통해 Apache 및 PHP, 그리고 각종 PHP 확장 모듈들을 설치하였습니다.
sudo apt update && sudo apt install -y \ apache2 \ php \ php-cli \ php-fpm \ php-dev \ php-pear \ libcurl4-openssl-dev \ php-curl \ php-mbstring \ php-xml \ php-mysql \ php-pgsql \ php-sqlite3 \ php-gd \ php-zip \ php-json \ php-bcmath \ php-intl \ php-readline \ php-memcached \ php-redis \ php-imagick \ php-xdebug \ composer \ unzip \ git \ curl
Bash
복사
php-dev는 Swoole을 컴파일하기 위해 필수적인 패키지입니다.
기타 확장들은 이후 개발 실험을 위한 환경을 고려하여 함께 설치하였습니다.

Swoole 소스 설치 과정입니다

Swoole은 현재 apt로 직접 설치가 불가능하기 때문에, GitHub의 공식 저장소에서 소스를 내려받아 직접 빌드하였습니다.
git clone https://github.com/swoole/swoole-src.git cd swoole-src phpize ./configure make sudo make install
Bash
복사
phpize는 PHP 확장을 컴파일할 수 있는 환경을 설정하는 명령어입니다.
make install 이후에는 swoole.so 파일이 생성되며, PHP에서 사용할 수 있게 됩니다.

PHP에 swoole 확장을 등록합니다

CLI에서 swoole을 사용할 수 있도록 확장 설정 파일을 생성합니다.
echo "extension=swoole.so" | sudo tee /etc/php/8.1/cli/conf.d/20-swoole.ini
Bash
복사
WebSocket 서버는 CLI 환경에서 실행하므로, CLI 전용 설정 경로에 등록하였습니다.

swoole 설치 여부 확인입니다

다음 명령어를 통해 swoole 확장이 정상적으로 등록되었는지 확인할 수 있습니다.
php -m | grep swoole
Bash
복사
출력 결과에 swoole이 포함되어 있으면 정상적으로 설치된 것입니다.

설치 후 소스 디렉토리 정리입니다

사용이 끝난 소스 디렉토리는 아래와 같이 삭제하였습니다.
cd .. rm -rf swoole-src/
Bash
복사

Apache 가상 호스트를 이용한 WebSocket 프록시 구성입니다

Swoole는 자체적으로 HTTP 서버를 구동하지만, 기존 Apache 웹 서버와 통합하기 위해 프록시 설정을 추가하였습니다.
이를 통해 도메인을 통해 Swoole WebSocket 서버에 접근할 수 있도록 구성하였습니다.

HTTP, HTTPS용 가상 호스트 설정입니다

<VirtualHost *:80> ServerAdmin example@domain.com ServerName example-domain.com RewriteEngine on ProxyRequests Off ProxyPreserveHost On ProxyPass /ws ws://localhost:9502/ ProxyPassReverse /ws ws://localhost:9502/ RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteRule /ws/(.*) ws://localhost:9501/$1 [P,L] ErrorLog "/var/log/apache2/example-domain.com-error.log" CustomLog "/var/log/apache2/example-domain.com-access.log" common </VirtualHost> <VirtualHost *:443> ServerAdmin example@domain.com ServerName example-domain.com SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCertificateKeyFile /home/example/ssl/current/example-domain_com_SHA256WITHRSA.key SSLCertificateFile /home/example/ssl/current/example-domain_com.crt SSLCACertificateFile /home/example/ssl/current/ChainCA/SectigoRSADomainValidationSecureServerCA.crt SSLCertificateChainFile /home/example/ssl/current/ChainCA/rsa-dv.chain-bundle.pem ErrorLog "/var/log/apache2/example-domain.com-ssl_error.log" CustomLog "/var/log/apache2/example-domain.com-ssl_access.log" common ProxyRequests Off ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Ssl "on" RequestHeader set X-Forwarded-Port "443" <Location "/ws"> ProxyPass ws://localhost:9502/ timeout=300 connectiontimeout=300 keepalive=On ProxyPassReverse ws://localhost:9502/ </Location> RewriteEngine On RewriteCond %{HTTP:Upgrade} =websocket [NC] RewriteCond %{HTTP:Connection} =Upgrade [NC] RewriteRule /ws(.*) ws://localhost:9501$1 [P,L] </VirtualHost>
Bash
복사
이 설정을 통해, wss://example-domain.com/ws 경로로 WebSocket 서버에 접근할 수 있게 됩니다.
SSL 인증서도 함께 적용하여 보안 연결을 지원하고 있습니다.

간단한 WebSocket 서버 예제입니다

Swoole을 이용하여 아래와 같이 기본적인 WebSocket 서버를 실행할 수 있습니다.
<?php $server = new Swoole\WebSocket\Server("0.0.0.0", 9502); $server->on("open", function ($server, $req) { echo "Connection opened: {$req->fd}\n"; }); $server->on("message", function ($server, $frame) { echo "Received message: {$frame->data}\n"; $server->push($frame->fd, "Server: {$frame->data}"); }); $server->on("close", function ($server, $fd) { echo "Connection closed: {$fd}\n"; }); $server->start();
PHP
복사
위 코드를 실행하면 9502 포트에서 WebSocket 서버가 동작하게 됩니다.
php websocket.php
Bash
복사

브라우저에서 WebSocket 연결 예제입니다

아래는 JavaScript를 이용한 클라이언트 연결 예제입니다.
const ws = new WebSocket("ws://localhost:9502"); ws.onopen = () => { ws.send("Hello from browser!"); }; ws.onmessage = e => { console.log("From server:", e.data); };
JavaScript
복사

마무리하며

Swoole을 활용하면 PHP에서도 충분히 WebSocket 기반의 실시간 통신 기능을 구현할 수 있다는 사실을 확인하였습니다.
기존의 요청-응답 기반 방식과는 다른 방식으로 서버를 구성할 수 있어 흥미로웠으며, 무엇보다도 C 언어로 개발된 확장인 만큼 성능과 안정성 측면에서 매우 우수하다는 인상을 받았습니다.
이제 이 환경을 기반으로 실시간 채팅 기능을 직접 구현해볼 계획이며, 앞으로는 Redis 연동이나 채팅방(Room) 기능, 메시지 브로드캐스트 등 다양한 기능을 실험해볼 예정입니다.