LoginSignup
13
13

More than 5 years have passed since last update.

[node.js]socket.io上でsessionを使う

Last updated at Posted at 2017-05-09

セッションをsocket.io上でつかう@Node.js

nodeでチャットアプリケーションを作っていて、セッションをwebsocketのイベント上で使いたかったので。
前回はexpress-sessionを使って、ログインを行った際に、ユーザー名をセッションに保存した。
socket.ioのイベントでチャットが送信されたらチャット情報をMongoDBに保存するのだがその際にユーザー名をセッションから取り出したい。
最初はhttpのセッションを何もせずに使えると思ったが、意外と準備が必要だった。
ハンドシェイクがどうとか書いてある記事もあったが、スタックオーバーフローの記事
それよりも簡単に宣言を行えるものがあったのでそれを採用した。

問題点とやったこと

app.js上でsocket.ioとexpress-sessionを宣言する記事が多かったが、自分は最初にディレクトリを作る際にexpress-generatorコマンドを使って、ひな形を生成したのでapp.jsと/bin/wwwができてしまった。
これがあだとなって、大変だった。

自分は/bin/wwwでsoket.io宣言とセッション使用をした。
おそらく非推奨

app.jsでexpress-session宣言、下準備

まず、app.js上でセッションの宣言、wwwでセッション情報を使うための下準備。
オプション等は前の記事に書いてある。

app.js
var express = require('express');
var app = express();
var session = require('express-session');
var sessionMiddleware = session({
  secret: 'secret',
  resave: false,
  saveUninitialized: false,
  cookie:{
  httpOnly: false,
  secure: false,
  maxage: 1000 * 60 * 30
}});
app.session = sessionMiddleware;
app.use(sessionMiddleware);

...

module.exports = app;

最後のmodule.exportsでapp変数が他のファイルでも参照できるようにしている。
また、sessionMiddleware変数をwwwファイルで使いたいので
app.session = sessionMiddleware;
appのプロパティとして渡している。

/bin/wwwでセッションをsocket上で使えるように

www
//app変数の取り出し
var app = require('../app');
//sessionMiddlewareの取り出し
var sessionMiddleware = app.session;
var debug = require('debug')('chat-app:server');
var http = require('http');
var mongoose = require('mongoose');
var Chat = mongoose.model('Chat');

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

var server = http.createServer(app);
var io = require('socket.io')(server);

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

//セッションをsocket上で使えるように
io.use(function(socket, next){
  sessionMiddleware(socket.request, socket.request.res, next);
});

長々と準備の文を書いたが、大事なので最初の2行とio.useのところ。これでセッションをつかえるようにしている。
app.jsで渡したappを取り出している。app.jsのモジュールエクスポートが重要。

セッションの使い方

基本的にここまでくれば
socket.request.session.プロパティ名 
でセッション情報が取り出せる。
今回は前記事で書いたようにrequest.session.usernameにユーザー名が入っているのでこれを取り出している。
でそのほかはmongoooseでmongodbに保存する作業。

www
io.sockets.on('connection',function(socket){
    console.log('connected');
    socket.on('chat message',function(message){
      var chat = new Chat();
      chat.message = message;
      chat.chat_id = "one";
      chat.user = socket.request.session.username ;
      chat.save(function(error,chat){
        console.log(message);
        if(error){
          console.log(error);
        }else{
          console.log("chat saved");
        }
      });
      io.sockets.emit('send message', chat);
    });
});

クライアントからメッセージが来たらMongoDBに保存してその情報をクライアントに送り返しているのがこのプログラム。

結果

スクリーンショット (64).png

チャットのヘッダーのところにsessionから取り出したユーザー名が表示されているので完了。

gituhub

Mongoのモデルとか、mongoose,socket.ioの使い方等はgithubにあげているので参照して下さい。

https://github.com/hikaru7719/chat_app

参考文献

スタックオーバーフロー

http://stackoverflow.com/questions/25532692/how-to-share-sessions-with-socket-io-1-x-and-express-4-x

13
13
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
13
13