[Laravel] 라라벨에서 Notifications 활용하기

[Laravel] 라라벨에서 Notifications 활용하기 updated_at: 2023-07-14 17:50

Notification 활용하기

라라벨에서 node socket과 통신을 하기위해 Notification 을 종종 사용합니다.
주로 사용하는 방식은 laravel -> notificaton -> redis(publish) -> socket(node) 입니다.
laravel 외의 것도 포함되므로 laravel 위주의 notification을 주로 설명 드리고 나머지는 간단히 개념만 잡고 넘어 가겠습니다.

Notification

Notification 생성

php artisan make:notification InvoicePaid

위와 같은 명령을 입력하면 아래와 같이 InvoicePaid.php가 생성됩니다.
기본적인 형태는 Invoice가 생성되면 메일로 보내는 것인데 우리는 redis로 보내는 기능을 만들려고 합니다.

- app
  - Notifications
    - InvoicePaid.php

InvoicePaid.php

................
use Illuminate\Notifications\Notification;

class InvoicePaid extends Notification
{
  use Queueable;

  public function __construct()
  {
  }

  public function via($notifiable)
  {
    ................
  }


  public function toMail($notifiable)
  {
    ................
  }


  public function toArray($notifiable)
  {
    ................
  }
}

Redis 로 보내는 코딩

InvoicePaid.php

................
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Redis;

class InvoicePaid extends Notification
{
  use Queueable;

  private $messages;

  /**
   * Create a new notification instance.
   * @param $type String add | substract | reset
   * @param $flag String users | deposits | withdrawals | settles | qna
   * @return void
   */
  public function __construct($messages)
  {
    $this->messages = $messages;
  }

  /**
   * Get the notification's delivery channels.
   *
   * @param  mixed  $notifiable
   * @return array
   */
  public function via($notifiable)
  {
    Redis::publish('InvoiceMessage', json_encode($messages)); // Redis::publish([key], [value]);
  }
}

메시지를 받아서 redis로 넣어주는 것까지 프로그램 되었습니다.

라라벨에서 Message 보내기

예제 1 Notification 직접호출

  • congtroller
................
use Notification;
use App\Notifications\InvoicePaid;

class InvoiceController extends Controller
{
  ................
  public function create() {
    Notification::send(null, new InvoicePaid([]);
  }
}

예제 2 Model을 사용하여 호출

Model을 이용하여 사용하는 방식입니다.
app > Models > Invoice.php

................
use Illuminate\Notifications\Notifiable;

class Invoice extends Model
{
  use Notifiable;
................
}
  • controller
................
use App\Notifications\InvoicePaid;
use App\Models\Invoice;

class InvoiceController extends Controller
{
  ................
  public function create() {
    $invoice = new Invoice;
    $invoice->notify(new InvoicePaid([]));
  }
}

nodeJs를 이용한 subscribe

이것을 설명하기전에 redis의 기본 기능중의 하나인 publish, subscribe의 기능을 간단히 알아야 합니다.
redis는 데이타의 저장/수정/삭제/가져오기 뿐만 아니라 publish, subscribe 기능을 제공하는데 어떤 데이타를 publish로 redis로 전달하면 redis는 즉각 이 데이타를 subscribe하는 어떤 곳으로 내보냅니다.
따라서 이 기능을 잘 활용하면 이종 언어간의 통신도 수월하게 할 수 있습니다.

  • node-redis.js
const redis = require('redis');
const client = redis.createClient.....
................
client.subscribe('InvoiceMessage'); // laravel 에서 Redis::publish() 에서 사용한 키값인 message
client.subscribe('other keys'); // subscribe 하고 싶은 다른 키값도 이렇게 계속적으로 정의하시면 됩니다.
// 위의 subscribe에서 특정 키를 정의하게 되면 아래에서 그 특정 키를 계속 리스닝합니다.
client.on('message', (channel, messages) => {
  switch (channel) { // 키값이 channel이됩니다.
    case 'InvoiceMessage':
      console.log(messages); // messages 는 Redis::publish() 의 value 가 됩니다.
      break;
    case 'other keys':
      break;
  }
});

여기까지가 laravel에서 redis를 통해 데이타를 보내고 그 데이타를 nodejs에서 redis 를 통해 받는 것을 처리 하였습니다.

[추가] nodejs에 redis로 통해 받은 데이타를 소켓을 이용하여 다시 내 보내기

저 같은 경우는 events라는 패키지를 사용하여 처리합니다.

  • events.js
const EventEmitter = require('events');
exports.myEmitter = new EventEmitter();
  • node-redis.js
const event = require('./events');
................
client.on('message', (channel, messages) => {
  switch (channel) { // 키값이 channel이됩니다.
    case 'InvoiceMessage':
      event.myEmitter.emit('InvoiceMessage', messages);
      break;
    case 'other keys':
      break;
  }
});
  • socket.js
................
const event = require('./events');

module.exports = function(io) {
  (function() {
    event.myEmitter.on('InvoiceMessage', (data) => {
      io.in(room).emit('InvoceIssued', data);
    });
  })();
................
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1

질문 및 답글