반응형

라라벨의 브로드캐스팅 기능을 활용해 소켓통신을 실습해보았다

blade템플릿을 사용하면 더 편할텐데 javascript만 사용하는 회사이기에 바닐라js로 시도

적용하는 과정 자체는 몇 단계 없는데 적용하는데 시간을 많이 썼다

csrf토큰을 받아온 후 listen하는 등의 작업을 통해 소켓연결 완료

config/app.php, .env, channels.php, Events/CommentPosted.php, config/broadcasting.php 까지 설정을 완료 후 적절하게 활용하면 된다.

pusher를 composer로 먼저 받기

composer require pusher/pusher-php-server

으로 라라벨에 설치해준 후

위에서 언급한 방식대로 설정해주면 되는데,

app.php

...
'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\\Auth\\AuthServiceProvider::class,
        Illuminate\\Broadcasting\\BroadcastServiceProvider::class, //<<----이친구를 주석해제
        Illuminate\\Bus\\BusServiceProvider::class,
        Illuminate\\Cache\\CacheServiceProvider::class,
        Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider::class,
 ....

.env

BROADCAST_DRIVER=pusher

...

PUSHER_APP_ID=xxxxxxxx
PUSHER_APP_KEY=xxxxxxx
PUSHER_APP_SECRET=xxxxxxxx
PUSHER_APP_CLUSTER=xxxxxx

pusher가입 후

https://dashboard.pusher.com/

Channels에 있는 앱으로 생성 후 나온 값들을 env에 넣어줘야함

channels.php

Broadcast::channel('comment.{boardId}', function ($user, $boardId) {
    // 게시판의 모든 사용자가 이 채널을 들을 수 있도록 설정
    $board = \\App\\Models\\Board::find($boardId);
    if (!$board) return false;

    // 이 예제는 간단하게 모든 사용자에게 접근을 허용합니다.
    return true;
});

구독채널 설정

Events/CommentPosted.php

<?php

namespace App\\Events;

use Illuminate\\Broadcasting\\Channel;
use Illuminate\\Queue\\SerializesModels;
use Illuminate\\Broadcasting\\PrivateChannel;
use Illuminate\\Broadcasting\\PresenceChannel;
use Illuminate\\Foundation\\Events\\Dispatchable;
use Illuminate\\Broadcasting\\InteractsWithSockets;
use Illuminate\\Contracts\\Broadcasting\\ShouldBroadcast;
use App\\Models\\Comment;

class CommentPosted implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $comment;

    public function __construct(Comment $comment)
    {
        $this->comment = $comment;
    }
    
    public function broadcastOn()
    {
        return new PrivateChannel('comment.' . $this->comment->board_id);
    }    

}

ShouldBroadcast를 상속받은 구현체를 만들어서 채널명과 구독방식 등을 정해둘 수 있다.

config/broadcasting.php

...

'connections' => [

        'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'useTLS' => false,
            ],
        ],
        
...

pusher를 활용해 설정할 때 env()에 담긴 이름은 .env에 지정해둔 설정을 따라가기 때문에 변경할 필요가 없고 통신방식을 확인할 때 useTLS정도만 확인하면 될 것이다. 이번엔 실습을 위해 http일반통신을 하기 위해 false설정

이후 js설정에서

<script src="https://cdn.jsdelivr.net/npm/laravel-echo/dist/echo.iife.min.js"></script>
    <script src="https://js.pusher.com/8.2.0/pusher.min.js"></script>
    
    ...

$.ajax({
                url: 'http://localhost:8000/csrf-token',
                type: 'get',
                success: function(data){
                    csrfToken = data.csrfToken;

                    // Pusher를 사용하는 경우의 설정 예제
                    Pusher.logToConsole = true;

                    var pusher = new Pusher('xxxxxxxx', { //key입력
                        cluster: 'xxxxxxx',
                        encrypted: false,
                        auth: {
                            headers: {
                                'X-CSRF-Token': data.csrfToken
                            }
                        }
                    });

                    var echo = new Echo({
                        broadcaster: 'pusher',
                        key: 'xxxxxx',
                        cluster: 'xxxxxxxx',
                        encrypted: false,  // 보안을 위해 true로 설정
                        auth: {
                            headers: {
                                'X-CSRF-TOKEN': data.csrfToken,  // CSRF 토큰 추가
                                'Authorization': 'Bearer ' + localStorage.getItem('accessToken')  // 사용자 토큰 추가
                            }
                        }
                    });
                    // Echo를 사용하여 댓글 채널 구독
                    echo.private('comment.' + globalBoardId)
                        .listen('CommentPosted', (event) => {
                            alert('댓글추가됨');
                    });
                },
                error: function(xhr){

                }
            });

두 Script 라이브러리를 import후에

csrf토큰을 헤더에 추가하여 pusher를 구독 하면 완료!

추가로 csrf토큰을 담지못하면 해당 auth에 문제가 생겨서 구독이 불가능하니 csrf토큰을 발급해서 헤더에 꼭 추가하기!

저는 간단하게 해당 게시글을 구독 후 댓글이 작성될 때마다 alert를 띄우도록 설정했습니다

 

한쪽에서 댓글을 추가 시 양쪽 페이지 모두 listen되어 alert창 팝업

 

Reference : https://laravel.kr/docs/5.8/broadcasting

 
반응형

'공부 > Laravel' 카테고리의 다른 글

Laravel 5.8 TestCode  (0) 2024.06.21

+ Recent posts