비동기 기능과 클라이언트에 알림을 보내기 위해 Reverb + Laravel Echo 조합을 사용하기로 했다. 이것을 결정했을 때가 해당 시스템의 Laravel 버전이 무려 5.8(... 이 버전에는 Reverb 라는 것은 존재하지도 않는다.)
일단 최신 버전 가까이는 가보자 싶어서 Laravel 10 까지 업그레이드 한 이후 진행하였다.
업그레이드에는 유료 프로그램을 사용하는 지름길이 있지만, 공식 업그레이드 문서와 함께 한 단계씩 차근차근 올리기만 하면 무료로도 얼마든지 가능하다.
주의 문서에도 명시되어 있지만, PHP8.2 이상의 버전이 필요하다.
Laravel Reverb의 설치는 사실 간단하다.
https://laravel.com/docs/10.x/reverb
여기에 나온 대로 따라가기만 하면 된다.
주의할 점은 v10과 v11의 과정과 사용하는 설정에 차이가 있기 때문에, 사용 중인 Laravel 버전에 맞는 문서를 참조해야 한다.
composer require laravel/reverb
reverb 패키지를 설치하고 나서 다음 명령어를 실행하면 기본적인 reverb 설정과 환경 변수 등이 추가 된다.
php artisan reverb:install
.env
파일을 열어보면 이전에 없던 REVERB_
가 붙은 변수들이 추가된 것을 확인할 수 있을 것이다.
REVERB_APP_ID=12345(예시)
REVERB_APP_KEY=qwertyui(예시)
REVERB_APP_SECRET=zxcvbn(예시)
대략 이런 식이다.
그리고 만약 아래의 값들이 없다면 작성해주는 것이 조금 더 헷갈리지 않을 수 있다.
REVERB_HOST=your_laravel_service_domain
REVERB_PORT=443(또는 80)
REVERB_SCHEME=https(또는 http)
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080(또는 다른 가능한 port)
이 값들은 config/reverb.php
파일을 열어보면 default 값이 적혀있으니 참고해서 자신의 환경에 맞게 작성하면 된다.
나의 경우 production 환경에서 8080을 사용하고, 개발 환경에서 다른 포트를 사용하기 위해 해당 port를 작성하고 방화벽에서도 port를 열어주었다. 이 부분을 놓치면, 이유없이 계속 작동이 되지 않아 많은 시간을 허비할 수 있다. (그렇다, 본인 얘기다...)
더 진행하기 전에 reverb:start
로 먼저 이상이 없는지 확인을 해본다.
php artisan reverb:start --debug
서버 단의 설정이 대략 끝났다면, 이제 클라이언트 쪽의 준비가 필요하다.
npm install --save-dev laravel-echo pusher-js
보다시피 laravel-echo와 함께 pusher-js를 같이 설치한다.
그리고 resources/js/bootstrap.js
파일을 열어보면 Echo에 관한 내용이 이미 작성되어 있지만 주석처리가 되어있을 것이다.
이를 간단히 주석해제하면 된다는 것이 공식 문서이지만, 나의 경우처럼 낮은 버전에서 억지로 기어올라(?)온 경우, 그 내용을 그대로 사용할 수 없다.
최신 버전에서는 프론트엔드 빌드를 위해 VITE가 기본적으로 사용되고 있지만, 저 버전에선 MIX가 기본이기 때문이다. VITE는 Laravel 9 기반 다른 프로젝트에서 사용해보기도 했고, 지금 이 프로젝트는 나 혼자 만들고 사용 중인 프로젝트가 아니라서 최대한 덜 손 대야 안전했기에, 우선 MIX 기반으로 그대로 두기로 했다. 크게 어려울 것은 없고 그냥 아래처럼 변수명 앞에 VITE_
대신 MIX_
라고 작성해주기만 하면 된다.
window.Echo = new Echo({
broadcaster: 'reverb',
key: process.env.MIX_REVERB_APP_KEY,
wsHost: process.env.MIX_REVERB_HOST,
wsPort: process.env.MIX_REVERB_PORT,
wssPort: process.env.MIX_REVERB_PORT,
forceTLS: (process.env.MIX_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
debug: true,
});
당연한 이야기일 수 있지만, 모든 내용을 굳이 bootstrap.js
에 다 담을 필요는 없다. 나는 echo.js
파일을 만들고 그 안에 채널 관련된 내용을 작성한 다음 bootstrap.js
에서 require
로 불러들이는 방식을 사용했다.
npm run dev
로 작성한 내용을 빌드해준다.
이 부분의 내용은 지금은 건너뛰도록 하겠다. 그렇게 어려운 내용도 아니고 여기는 사용하고자 하는 대로 작성만 하면 되니까.
Event의 broadcastOn에서 반환하는 채널명과 Echo에서 사용하는 채널이 동일해야 한다는 점만 놓치지 않으면 된다.
추후에 별도로 작성해 둘 생각이다.
문제는 바로 여기다. 여기까지 한 다음, 환장하는 일이 발생한다.
분명 문서를 따라가며 하라는 대로 다 한 것 같았는데, websocket이 아예 작동할 기미가 보이지 않는 것이다.
솔직히 아직도 공식 문서만 따라가보면 내가 어디에서 무슨 내용을 놓쳤는지 모르겠다;;
구글링의 구글링의 구글링 끝에 웹서버에 추가 설정이 필요하다는 것을 알아냈을 뿐이다.
apache라면 httpd.conf
에, nginx라면 nginx.conf
또는 conf.d
디렉토리 안에 있는 설정 파일에 아래 내용을 추가해주어야 한다.
location /app/ {
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;
}
location /apps/ {
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;
}
물론 0.0.0.0과 8080 포트는 자신의 환경에 맞게 수정해줘야 한다.
주의 혹시 기존에 사용하던 다른 route에 /app
또는 /apps
를 사용하고 있었다면, 기존 route를 변경해줘야 한다.
config/reverb.php
에서 reverb가 다른 route를 사용하도록 설정할 수 있는지는 잘 모르겠다. (아마도 되지 않을까?)
모든 것이 잘 되었다면 php artisan reverb:start
로 웹소켓을 통한 알림이 잘 작동할 것이다.
Job과 Event를 통한 알림 전송의 경우 queue:work
도 선행되어야 한다.
개발 단계에서 이상이 없다면 이 명령들의 실행은 supervisor
에서 실행하는 것이 가장 간단하다. 특히 queue
의 경우 일일이 재시작을 신경쓰지 않아도 되기 때문에, laravel schedule이나 crontab 등을 통해 실행하려고 하지 말자. supervisor가 최고다.