LoginSignup
26
25

More than 5 years have passed since last update.

Socket.IOでメッセージが届いたことを確認する

Last updated at Posted at 2015-05-06

WebSocket使ってると、クライアントからサーバーにメッセージ送って、届いたのがはっきりしてから何かしたいことがあったりします。WebSocketの仕様その物にはそういう機能は無いようですが、Socket.IOにはそういう機能があったのでこれが使えました。
(低レベルの話を期待していた方、済みません)

ドキュメントに書いてあることそのままではあるんですが:Sending and getting data (acknowledgements)

Socket.IOのacknowledgements機能

emitするクライアント側のコード、サーバー側のonで待ち受けるブロックのコード、のそれぞれでコールバック関数を登録することで、クライアントからのメッセージが届いた時の処理を書けます。処理を書けるということは、届いたことが確認できるということです。

client.js
// クライアント側
var ws = io();
// 色々初期化処理
ws.emit("post", data, function onack(response) {
  // データが届いたことを確認できた
  doSomethingWith(response);
});
server.js
// サーバー側
// 色々初期化処理
var io = require("socket.io")(server);
io.on("connection", function(user) {
  user.on("post", function(data, ack) {
    // dataをDBに保存したりする
    // ユニークキーが割り振られたりする
    data.id = dbRecord.id;
    ack(data);// データが届いたことの確認、兼、追加データの通知
  });
});

Promiseにしてみる

これだけで終わってもアレなので、Promsieにしてみるとこんな感じでしょうか。

client-with-promise.js
// クライアント側
var ws = io();
// 色々初期化処理
post(data).then(function(response) {
  doSomethingWith(response);
});

function post(data) {
  return new Promise(function(resolve, reject) {
    ws.emit("post", data, resolve);
  });
}

ストリームにしてみる

これだけで終わってもアレなので、WAHTWG Streamsのストリームにしてみるとこんな感じでしょうか。

client-with-streams.js
// クライアント側
var ws = io();
// 色々初期設定
userActionStream // 「保存ボタンを押す」とかのアクション
  .pipeThrough(actionToData()) // DOMツリーからデータ集めて整形
  .pipeThrough(post(ws)) // ここの話なので下に実装置いときます
  .pipeTo(soSomethingWithResponse());

function post(ws) {
  return new TransformStream({
    transform: function(data, enqueue, done) {
      ws.emit("post", data, function ack(response) {
        enqueue(response);
        done();
      });
    }
  });
}

(2015年5月3日版の仕様とリファレンス実装を使っています)

26
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
26
25