31
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Node] websocket + redis pub/subでサーバ発でclientに通知を送る

Last updated at Posted at 2018-09-30

Server発でclientにメッセージを送りたくなった

元々nodeで作ったwebsocket serverでclient側と双方向通信をしていたんですが、別サーバやbatch処理などでの更新処理をトリガーとしてclient(の従来で使用しているchannel)にメッセージを送りたくなりました。
そこでいろいろ探してたら、redisにpub/sub機能というのがあり、それを使えば上手くいきそうなのでやってみました。

実装のイメージ

# 使ったモジュール * [redis pub/sub](https://redis.io/topics/pubsub) * 他のサーバでの変更を検知するために使用 * [socket.io-emitter](https://github.com/socketio/socket.io-emitter) * サーバ側からclientにメッセージを送るためのモジュール * [socket.io-redis](https://github.com/socketio/socket.io-redis) * 異なるプロセスやサーバ間で動いているwebsocketサービスで接続先情報をredisで共有し、正常にemitやbroadcastを行えるようにするためのモジュール

インストール


$ npm i -S redis
$ npm i -S socket.io
$ npm i -S socket.io-emitter
$ npm i -S socket.io-redis

#実装
まず、従来のsocketサービスの接続先を共有するために、socket.io-redisを入れる。


// socket-server
const io = require('socket.io')(); // for socket server
const socketRedis = require('socket.io-redis');

// 接続先情報をredisに保存
io.adapter(socketRedis({
  host: 'localhost', //サンプルなので一旦ローカルのredisを参照
  port: 6379,
}));

// 〜〜〜従来のsocket処理〜〜〜

次に、サーバ発のメッセージを送るためにio-emitterを入れる。

// 先ほどと同じredis情報を渡して起動することで、接続情報を共有
const emitter = ioEmitter({
  host: 'localhost',
  port: 6379,
});

最後にredisのsubscriberを作成し、それをトリガーとしてio emitterでclientにemitする。

const redis = require('redis');
// subscribeする用のredis clientを作成
// ここではめんどくさかったので、接続情報を登録するものと同じものを使用
const Subscriber = redis.createClient(6379, 'localhost');

// redis-publisherからのメッセージを受け取るチャンネルを登録
Subscriber.subscribe('SUBSCRIBE_CHANNEL');

exports.register = (emitter) => {
  Subscriber.on('message', (channel, message) => {
    switch (channel) {
      // 該当のチャンネルにメッセージが飛ばされたら場合分けして処理
      case 'SUBSCRIBE_CHANNEL':
        emitter.to('CLIENT_CHANNEL').emit('Hello!! I am redis-subscriber.');
        break;
    }
  });
};

これで、別サーバにからredisのpublisherを使って「SUBSCRIBE_CHANNEL」にメッセージを送れば、フロントで「CLIENT_CHANNEL」を開いている全員に向けて「Hello!! I am redis-subscriber.」というメッセージを通知できる。

最後に

redisのpub/subとsocket.io-emitterを使ったら、他のサーバと同期を取りながらいい感じにフロントに通知を送ることができるようになりました。
サンプルはここに置いておきましたのでよろしければご参照ください。

間違い等あったら教えてくれると嬉しいです。

31
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?