Help us understand the problem. What is going on with this article?

socket.io 1.0 のハンドシェイク(セッション共有)

More than 5 years have passed since last update.

socket.io 1.0 では connect っぽく middleware として書けるようになりました。

socket.io 1.0 のハンドシェイク!

socket.requestRequest オブジェクトが受け取れるのでそれを利用します。
(以下、Express 4.x の場合)

server.coffee
Session = require('express-session').session.Session

COOKIE_SECRET = 'himitsu-dayo'
COOKIE_KEY    = 'sid'

#
# 途中省略
#

# Socket.io
io = require('socket.io')(server)

# セッション共有
io.use (socket, next)->

    # クッキーからセッション ID を取得する
    cookie = require('cookie').parse socket.request.headers.cookie
    cookie = require('cookie-parser/lib/parse').signedCookies cookie, COOKIE_SECRET
    sessionID = cookie[COOKIE_KEY]

    # セッション情報を取得する
    sessionStore.get sessionID, (err, sessionData)->

        # セッション情報の取得成功!
        if !err and sessionData

            # 新しく Session を作成
            socket.session = new Session({sessionID: sessionID, sessionStore: sessionStore}, sessionData)
            next()

        # セッション情報の取得失敗 :(
        else
            next if err then err.message else 'ハンドシェイク失敗だよ!'

# 接続
io.on 'connection', (socket)->

    # セッション!
    session = socket.session 

    #
    # 以下いろいろ
    # 

※ 0.9 までの connect.utils.parseSignedCookies は使えなくなったようです。 cookie-parser モジュールを使いましょう。

ちなみに・・・ socket.io 0.9 までのハンドシェイクは

0.9 までは下のように、 io.set('authorization', fun); のように書いていました。

server.coffee
io.set 'authorization', (handshakeData, callback)->

    # クッキーからセッション ID を取得する
    cookie = require('cookie').parse decodeURIComponent handshakeData.headers.cookie
    cookie = connect.utils.parseSignedCookies cookie, COOKIE_SECRET
    sessionID = cookie[COOKIE_KEY]

    # セッション情報を取得する
    sessionStore.get sessionID, (err, sessionData)->

        # セッション情報の取得成功!
        if !err and sessionData

            # 新しく Session を作成
            handshakeData.session = new Session sessionID: sessionID, sessionStore: sessionStore, sessionData
            callback(null, true)

        # セッション情報の取得失敗 :(
        else
            callback (if err then err.message else 'ハンドシェイク失敗だよ!'), false 

#
# 以下省略
# 

並べてみるとあまり変わらないように見えるけど、 middleware として書けることでセッション共有以外にもいろいろやりやすくなったと思います。

私のプロジェクトではハンドシェイクの後に middleware でユーザ情報を取り出したりとか書いたりしてます。

Store

タイトルのハンドシェイクとはあまり関係ないけど Store についても軽く触れておきます。

別のプロセスやサーバ間で共有するための store は Adapter という仕組みで実現します。

0.9 までは socket.ioRedis 用のクラスが最初から用意されてたけど、1.0 (pre4) では用意されてないようです。

現状、 Redis を使う場合は別の開発者の socket.io-redis がよさそうです。

こんな感じで、

server.coffee
# Redis アダプタ
RedisAdapter = require('socket.io-redis')(host: 'localhost', port: 6379)

# Socket.io
io = require('socket.io')(server, { adapter: RedisAdapter })

ソースを軽く覗いたら Pub/Sub とか勝手にやってくれそうな感じ。

最後に

この記事はまだ正式リリース前の socket.io 1.0.0-pre5 をベースに書いています。
たぶん正式版でも動く...はず!

1.0.2 で動きました。

こちらからは以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした