Laravel Reverb
번역일: 2026년 6월 20일
Laravel Reverb
소개
Laravel Reverb는 빠르고 확장 가능한 실시간 WebSocket 통신 기능을 Laravel 애플리케이션에 직접 제공합니다. Laravel의 이벤트 브로드캐스팅 도구와 자연스럽게 통합되므로, 별도의 외부 서비스 없이도 실시간 기능을 구현할 수 있습니다.
설치
install:broadcasting Artisan 명령어로 Reverb를 설치할 수 있습니다:
php artisan install:broadcasting설정
install:broadcasting 명령어를 실행하면 내부적으로 reverb:install 명령어가 함께 실행되며, 합리적인 기본값으로 Reverb가 설치됩니다. 설정을 변경하려면 .env 파일의 환경 변수를 수정하거나, config/reverb.php 설정 파일을 직접 편집하면 됩니다.
애플리케이션 인증 정보
클라이언트가 Reverb 서버에 연결하려면 서버와 클라이언트 간에 "애플리케이션" 인증 정보를 교환해야 합니다. 이 인증 정보는 서버 측에서 설정하며, 클라이언트 요청을 검증하는 데 사용됩니다. 아래 환경 변수로 인증 정보를 정의합니다:
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret허용 오리진
클라이언트 요청을 허용할 오리진(origin)을 제한하려면 config/reverb.php의 apps 섹션에서 allowed_origins 값을 수정하세요. 목록에 없는 오리진에서 오는 요청은 거부됩니다. 모든 오리진을 허용하려면 *를 사용하세요:
'apps' => [
[
'app_id' => 'my-app-id',
'allowed_origins' => ['example.co.kr'],
// ...
]
]다중 애플리케이션
Reverb는 기본적으로 설치된 애플리케이션 하나에 대해 WebSocket 서버를 제공합니다. 그러나 단일 Reverb 인스턴스로 여러 애플리케이션을 동시에 서비스하는 것도 가능합니다.
예를 들어, 하나의 Laravel 애플리케이션에서 Reverb를 통해 여러 프로젝트에 WebSocket 연결을 제공하고 싶다면, config/reverb.php에 여러 apps를 정의하면 됩니다:
'apps' => [
[
'app_id' => 'my-app-one',
// ...
],
[
'app_id' => 'my-app-two',
// ...
],
],SSL
대부분의 경우, 보안 WebSocket 연결(WSS)은 요청이 Reverb 서버로 프록시되기 전에 Nginx 같은 업스트림 웹 서버에서 처리합니다.
다만 로컬 개발 환경에서는 Reverb 서버가 직접 보안 연결을 처리하는 것이 편리할 수 있습니다. Laravel Herd의 보안 사이트 기능을 사용하거나, Laravel Valet에서 secure 명령어를 실행한 경우, Herd나 Valet이 생성한 인증서를 Reverb에서 사용할 수 있습니다. 이를 위해 REVERB_HOST 환경 변수에 사이트 호스트명을 설정하거나, 서버 시작 시 직접 옵션으로 전달하세요:
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"Herd와 Valet 도메인은 localhost로 해석되므로, 위 명령어를 실행하면 Reverb 서버에 wss://laravel.test:8080 주소로 보안 WebSocket 프로토콜(wss)을 통해 접근할 수 있습니다.
인증서를 직접 지정하려면 config/reverb.php의 tls 옵션을 설정하세요. PHP SSL 컨텍스트 옵션에서 지원하는 모든 항목을 사용할 수 있습니다:
'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],서버 실행
reverb:start Artisan 명령어로 Reverb 서버를 시작합니다:
php artisan reverb:start기본적으로 서버는 0.0.0.0:8080에서 시작되어 모든 네트워크 인터페이스에서 접근할 수 있습니다.
호스트나 포트를 직접 지정하려면 --host와 --port 옵션을 사용하세요:
php artisan reverb:start --host=127.0.0.1 --port=9000또는 .env 파일에 REVERB_SERVER_HOST와 REVERB_SERVER_PORT 환경 변수를 정의하는 방법도 있습니다.
NOTE
REVERB_SERVER_HOST / REVERB_SERVER_PORT와 REVERB_HOST / REVERB_PORT는 서로 다른 역할을 합니다. 전자는 Reverb 서버 자체가 바인딩할 호스트와 포트를 지정하고, 후자는 Laravel이 브로드캐스트 메시지를 보낼 대상 주소를 지정합니다. 예를 들어 프로덕션 환경에서 공개 호스트명의 443 포트로 들어온 요청을 내부 0.0.0.0:8080의 Reverb 서버로 라우팅하는 경우, 환경 변수는 다음과 같이 설정합니다:
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_HOST=ws.example.co.kr
REVERB_PORT=443디버깅
성능을 위해 Reverb는 기본적으로 디버그 정보를 출력하지 않습니다. 서버를 통해 오가는 데이터 스트림을 확인하려면 reverb:start 명령어에 --debug 옵션을 추가하세요:
php artisan reverb:start --debug재시작
Reverb는 장시간 실행되는 프로세스이므로, 코드 변경 사항은 서버를 재시작해야 반영됩니다. reverb:restart Artisan 명령어를 사용하세요:
php artisan reverb:restartreverb:restart 명령어는 서버를 중지하기 전에 모든 연결을 안전하게 종료합니다. Supervisor 같은 프로세스 매니저를 사용 중이라면 모든 연결이 종료된 후 자동으로 서버가 재시작됩니다.
모니터링
Reverb는 Laravel Pulse와의 연동을 통해 모니터링할 수 있습니다. Reverb의 Pulse 연동을 활성화하면 서버에서 처리 중인 연결 수와 메시지 수를 추적할 수 있습니다.
연동을 활성화하려면 먼저 Pulse를 설치한 후, config/pulse.php 설정 파일에 Reverb 레코더를 추가합니다:
use Laravel\Reverb\Pulse\Recorders\ReverbConnections;
use Laravel\Reverb\Pulse\Recorders\ReverbMessages;
'recorders' => [
ReverbConnections::class => [
'sample_rate' => 1,
],
ReverbMessages::class => [
'sample_rate' => 1,
],
// ...
],다음으로, Pulse 대시보드에 각 레코더에 해당하는 카드를 추가합니다:
<x-pulse>
<livewire:reverb.connections cols="full" />
<livewire:reverb.messages cols="full" />
...
</x-pulse>연결 활동 정보는 주기적인 폴링으로 기록됩니다. Pulse 대시보드에서 이 정보가 올바르게 표시되려면 Reverb 서버에서 pulse:check 데몬을 실행해야 합니다. 수평 확장 구성을 사용하는 경우에는 서버 중 하나에서만 이 데몬을 실행하면 됩니다.
프로덕션 환경에서 Reverb 운영
WebSocket 서버는 장시간 실행되는 특성이 있으므로, 서버가 가용 자원 내에서 최적의 연결 수를 처리할 수 있도록 서버와 호스팅 환경을 최적화해야 할 수 있습니다.
NOTE
Laravel Cloud는 Laravel Reverb 클러스터 기반의 완전 관리형 WebSocket 인프라를 제공합니다. 인프라를 직접 관리하지 않고도 Reverb 기반 애플리케이션을 손쉽게 확장하고 배포할 수 있습니다.
열린 파일 수 제한
각 WebSocket 연결은 클라이언트나 서버가 연결을 끊을 때까지 메모리에 유지됩니다. Unix 계열 환경에서는 각 연결이 파일로 표현되는데, 운영체제와 애플리케이션 레벨 모두에서 동시에 열 수 있는 파일 수에 제한이 있습니다.
운영체제 설정
Unix 기반 운영체제에서는 ulimit 명령어로 현재 허용된 열린 파일 수를 확인할 수 있습니다:
ulimit -n이 명령어는 사용자별로 허용된 열린 파일 수 제한을 보여줍니다. /etc/security/limits.conf 파일을 편집해 이 값을 변경할 수 있습니다. 예를 들어, forge 사용자의 최대 열린 파일 수를 10,000으로 늘리려면 다음과 같이 설정합니다:
# /etc/security/limits.conf
forge soft nofile 10000
forge hard nofile 10000이벤트 루프
Reverb는 내부적으로 ReactPHP 이벤트 루프를 사용해 서버의 WebSocket 연결을 관리합니다. 기본적으로 stream_select 기반의 이벤트 루프가 사용되며, 별도의 PHP 확장이 필요 없습니다. 다만 stream_select는 일반적으로 1,024개의 열린 파일로 제한됩니다. 따라서 1,000개 이상의 동시 연결을 처리해야 한다면 이 제한이 없는 다른 이벤트 루프로 전환해야 합니다.
ext-uv 확장이 설치되어 있으면 Reverb가 자동으로 해당 루프로 전환합니다. PECL을 통해 설치할 수 있습니다:
pecl install uv웹 서버
대부분의 경우 Reverb는 외부에 노출되지 않는 내부 포트에서 실행됩니다. 트래픽을 Reverb로 전달하려면 리버스 프록시를 설정해야 합니다. Reverb가 0.0.0.0:8080에서 실행되고 Nginx를 사용하는 경우, 다음과 같이 리버스 프록시를 설정할 수 있습니다:
server {
...
location / {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://0.0.0.0:8080;
}
...
}WARNING
Reverb는 /app 경로에서 WebSocket 연결을 수신하고, /apps 경로에서 API 요청을 처리합니다. 웹 서버가 이 두 URI를 모두 처리할 수 있도록 설정해야 합니다. Laravel Forge로 서버를 관리하는 경우 Reverb 서버 설정이 기본으로 올바르게 구성됩니다.
웹 서버는 일반적으로 서버 과부하를 방지하기 위해 허용 연결 수를 제한합니다. Nginx에서 허용 연결 수를 10,000으로 늘리려면 nginx.conf의 worker_rlimit_nofile과 worker_connections 값을 수정하세요:
user forge;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
worker_rlimit_nofile 10000;
events {
worker_connections 10000;
multi_accept on;
}위 설정은 프로세스당 최대 10,000개의 Nginx 워커를 허용하고, Nginx의 열린 파일 제한도 10,000으로 설정합니다.
포트
Unix 기반 운영체제는 서버에서 열 수 있는 포트 수를 제한합니다. 다음 명령어로 현재 허용된 포트 범위를 확인할 수 있습니다:
cat /proc/sys/net/ipv4/ip_local_port_range# 32768 60999위 출력은 각 연결마다 빈 포트가 하나씩 필요하므로 서버가 최대 28,231개(60,999 - 32,768)의 연결을 처리할 수 있음을 의미합니다. 더 많은 연결이 필요하다면 수평 확장을 권장하지만, /etc/sysctl.conf에서 허용 포트 범위를 늘리는 방법도 있습니다.
프로세스 관리
대부분의 경우 Supervisor 같은 프로세스 매니저를 사용해 Reverb 서버가 항상 실행 상태를 유지하도록 해야 합니다. Supervisor로 Reverb를 실행한다면, Supervisor가 연결 처리에 필요한 파일을 충분히 열 수 있도록 supervisor.conf의 minfds 설정을 업데이트하세요:
[supervisord]
...
minfds=10000수평 확장
단일 서버로 처리할 수 없을 만큼 많은 연결이 필요하다면, Reverb 서버를 수평으로 확장할 수 있습니다. Reverb는 Redis의 publish/subscribe 기능을 활용해 여러 서버에 걸친 연결을 관리합니다. 하나의 Reverb 서버가 메시지를 수신하면 Redis를 통해 다른 모든 서버에 해당 메시지를 전파합니다.
수평 확장을 활성화하려면 .env 파일에서 REVERB_SCALING_ENABLED 환경 변수를 true로 설정하세요:
REVERB_SCALING_ENABLED=true다음으로, 모든 Reverb 서버가 통신할 중앙 Redis 서버를 별도로 준비해야 합니다. Reverb는 애플리케이션에 설정된 기본 Redis 연결을 사용해 모든 Reverb 서버에 메시지를 전파합니다.
확장 옵션을 활성화하고 Redis 서버를 설정한 후에는, 해당 Redis 서버와 통신할 수 있는 여러 서버에서 reverb:start 명령어를 실행하면 됩니다. 이 Reverb 서버들은 들어오는 요청을 균등하게 분산하는 로드 밸런서 뒤에 배치해야 합니다.
이벤트
Reverb는 연결 및 메시지 처리 생명주기 동안 내부 이벤트를 발생시킵니다. 이 이벤트를 리슨하면 연결이 관리되거나 메시지가 교환될 때 원하는 동작을 수행할 수 있습니다.
Reverb가 발생시키는 이벤트 목록은 다음과 같습니다:
Laravel\Reverb\Events\ChannelCreated
채널이 처음 생성될 때 발생합니다. 일반적으로 첫 번째 클라이언트가 특정 채널을 구독할 때 발생합니다. Laravel\Reverb\Protocols\Pusher\Channel 인스턴스를 전달받습니다.
Laravel\Reverb\Events\ChannelRemoved
채널이 제거될 때 발생합니다. 일반적으로 마지막 클라이언트가 채널 구독을 해제할 때 발생합니다. Laravel\Reverb\Protocols\Pusher\Channel 인스턴스를 전달받습니다.
Laravel\Reverb\Events\ConnectionPruned
서버가 비활성 연결을 정리할 때 발생합니다. Laravel\Reverb\Contracts\Connection 인스턴스를 전달받습니다.
Laravel\Reverb\Events\MessageReceived
클라이언트 연결로부터 메시지를 수신할 때 발생합니다. Laravel\Reverb\Contracts\Connection 인스턴스와 원시 문자열 $message를 전달받습니다.
Laravel\Reverb\Events\MessageSent
클라이언트 연결로 메시지를 전송할 때 발생합니다. Laravel\Reverb\Contracts\Connection 인스턴스와 원시 문자열 $message를 전달받습니다.