[Laravel] 라라벨에서 Notifications 활용하기
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);
});
})();
................