【初心者】じゃんけんアプリ作ってみた(expressとsocket.ioでセッションの共有)【node.js】

こんにちは、よいこです。

初投稿ですが、日々勉強したことを備忘録的に残していこうという思いではじめました。
今日はexpressとsocket.ioでセッションを共有する方法についてまとめたいと思います。

【背景】

最近流行ってるし、今後も続きそうだなーという思いでnode.jsを勉強しはじめたものの、ただ勉強するだけではつまらないと思いアプリを作りつつ勉強しようと思いました(ちなみにこの時点でnode.jsの知識はほぼゼロ。サーバサイドをjsで記述できるくらいしか知らない始末。。なんならjsも大してわかってない。)。

何も知らないのでHello world的な感覚でとりあえずじゃんけんアプリでも作ってみるか、と思い色々しらべていくにつれあれもやりたい、これもやりたいとなり結果つまずくことに・・・。かなり時間がかかったもののその中で学んだことをちょこちょこと書いていきたいと思います。

今回はexpressのセッションとsocket.ioのセッションを共有するよ!というお話。

【モジュール】
・express (4.17.1)
・socket.io (2.2.0)
・express-session (1.16.2)
・express-socket.io-session (1.3.5) ←※これが今回の要!
・http (expressに付属?)
・ejs (2.6.2)
・body-parser (1.19.0)

【手順まとめ】
0. 各種モジュールをプロジェクトフォルダにダウンロード (npm install --save モジュール名[ex:npm install --save express])
1. モジュールの使用宣言[ex:const express = require('express')]
2. express-sessionの設定[app.use(session)]
3. socket.ioとのセッション共有設定[io.use(sharedsession(session))]
4. 各種routerの使用宣言
※順番が重要です。この順番を適当に書いていたために一向にうまくいかず・・。

 【フォルダ構成】

 socketsample
├package-lock.json
├package.json
├server.js

├─node_modules

├─public
│ ├─css
│ │ duel.css
│ │ login.css
│ │ main.css
│ │
│ ├─image
│ │ p300x300.jpg
│ │ r300x300.jpg
│ │ s300x300.jpg
│ │
│ └─js
│ duel.js
│ index.js

├─routes
│ duel.js
│ index.js

└─views
duel.ejs
index.ejs

ソースコード

https://github.com/yoiko0328/socketsample

server.js

// モジュールの読込
const express = require('express');
const ejs = require('ejs');
const bodyParser = require('body-parser');
const app = express();
const http = require('http').Server(app);
const PORT = 3030;
const io = require('socket.io')(http);
const sharedsession = require("express-socket.io-session");
const session = require("express-session")({
    secret: "my-secret",
    resave: true,
    saveUninitialized: true,
    cookie: {
        httpOnly: true,
        secure: false,
        maxage: 1000 * 60 * 30
    }
});

// expressのテンプレートエンジンにejsをセット
app.set('ejs'ejs.renderFile);

// ミドルウェア関数使用宣言
app.use(session);
app.use(bodyParser.urlencoded({ extended: true }));

// publicフォルダの公開
app.use(express.static('public'));

// expressのsessionとwebsocketのセッションを共有
io.use(sharedsession(session));

// router使用宣言
app.use('/'require('./routes/index'));
app.use('/duel'require('./routes/duel'));

// ポートのlisten開始
http.listen(PORT, () => {
    console.log('server listening. Port:' + PORT);
});

/* websocketの処理 */
var player1 = "";
var player2 = "";
var room = "";
var selectedHand_1 = "";
var selectedHand_2 = "";
var win = 0;
var def = 0;
var draw = 0;
var duel = 0;

io.on('connection'socket => {
    /* duelページの処理 */
    // プレイヤー名のSet
    socket.on('checkUserName', () => {
        if (player1 === socket.handshake.session.userName) {
            socket.join(room);
            if(player2){
                io.to(room).emit('start'player1player2room);
                io.to(room).emit('showResult'windefdrawduel);
            }
        }

login.js

const express = require('express');
const router = express.Router();
var title;

// GETリクエス
router.get('/'function(reqres) {
    title = 'Login';
    // セッションに名前が保存されていればbattleページへ遷移
    if (req.session.userName) {
        title = 'Duel' + '(' + req.session.userName + ')';
        res.redirect('http://localhost:3030/duel');
    }else{
        res.render('.././views/index.ejs', { title: title });
    }
});

// POSTリクエス
router.post('/'function (reqres) {
    title = 'Login';
    res.render('.././views/index.ejs', { title: title });
});

module.exports = router;

【結果】

f:id:yoiko0328:20190916000453p:plain

無事にセッション情報の共有ができました!

【最後に】

これからも日々はまったポイントについて投稿していきたいと思います。

取り急ぎはexpressの使い方、socket.ioの使い方については別途記事を書いていく予定です。