【mongoDB】Node + Socket.IO で簡単なチャットアプリの作成【9日目】

2012.12.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、クラスメソッドアドベントカレンダー【9日目】担当のうえじゅんです。
【CoffeeScript編】Node + Socket.IO で簡単なチャットアプリの作成 をベースにmongoDBを利用しデータの永続化をしてみましょう。

アドベントカレンダーはDevLOVEでも書いていますので、よければそちらも見てください。
【17日目】プロフェッショナルをつなぐ

mongoDBのインストール

まずはmongodbのインストールからです。

なお、今回はMacにインストールを前提としています。

MongoDB Downloads から「OS X 64-bit」の「2.2.2」をダウンロードします。

ダウンロードしたものを解凍し、任意の場所に配置します。
配置後、パスを通してください。

(例)
export PATH=$PATH:/Users/yourname/Tools

ターミナルでコマンドを入力をして以下のように表示されれば無事インストール完了です。

mongo --version
MongoDB shell version: 2.2.2

 nodeの環境構築

 nodeからmongodbに接続するためにはmongooseを利用します。
そのため、package.jsonにmongooseを追記します。

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app"
  },
  "dependencies": {
    "express": "3.0.0rc5",
    "jade": "*",
    "socket.io": "*",
    "mongoose": "*"
  }
}

追記が終了したら、「npm install」を実行します。

mongoDBとの連携

前回のコードを修正します。

「app.coffee」

###*
 * Module dependencies.
###

express = require 'express'
http = require 'http'
path = require 'path'
io = require 'socket.io'
message = require './models/message'

app = express()
server = http.createServer app
io = io.listen server

app.configure ->
  app.set 'port', process.env.PORT || 3000
  app.set 'views', __dirname + '/views'
  app.set 'view engine', 'jade'
  app.use express.favicon()
  app.use express.logger 'dev'
  app.use express.bodyParser()
  app.use express.methodOverride()
  app.use app.router
  app.use express.static path.join __dirname, "public"

app.configure 'development', ->
  app.use express.errorHandler()

server.listen app.get 'port'

io.sockets.on 'connection', (socket) ->
  message.find (err, messages) ->
    throw err if err
    socket.emit 'messeges:show', { messages: messages}

  socket.on 'message:send', (data) ->
    msg = new message()
    msg.text = data.message

    msg.save (err) ->
      throw err if err
      io.sockets.emit 'message:receive', { message: data.message }

requireを追加するのを忘れないようにしてください。
初回のみmongoDBから全件取得してクライアント側に渡しています。
クライアント側からメッセージを受信した際にmongoDBに新規でデータを追加しています。

「chat.coffee」

socket = io.connect()

socket.on 'messeges:show', (data) ->
  for message in data.messages
    $("div#chat-area").prepend "<div>" + message.text + "</div>"

socket.on 'message:receive', (data) ->
  $("div#chat-area").prepend "<div>" + data.message + "</div>"

send = ->
  msg = $("input#message").val()
  $("input#message").val ""
  socket.emit 'message:send', message: msg

"messeges:show"イベントを受けたら、メッセージを1行ずつ表示するようにしています。

新規に追加します。

「message.coffee」

mongo = require 'mongoose'
mongo.connect 'mongodb://localhost/cmapp'
 
Schema = mongo.Schema
 
Message = mongo.model 'messages', new Schema
  text: String
  created_at: {type: Date, default: Date.now}
  updated_at: {type: Date, default: Date.now}

module.exports = Message

まず"mongoose"をrequireしています。
"mongo.connect"にてmongoDBの接続先を指定しています。
今回はローカルに"cmapp"としています。

"Message = mongo.model 'messages', new Schema"が定義となります。
ここでは、text、created_at、updated_atを指定しています。
created_atとupdated_atにはデフォルトで現在日付をセットするために、"type: Date, default: Date.now"としています。

これだけの修正と追加で完了です。

あとはコンパイルをしましょう。

coffee -cbo . coffee/

実行

mongoDBを起動します。
mongoDBのデータを配置するフォルダを用意して以下のコマンドを実行してください。

mongod --nojournal --noprealloc --dbpath .

今回はジャーナル機構やデータファイルを先に確保する機構を無効化しています。
容量等を気にしないのであれば、mongodだけでオプションを指定しなくても大丈夫です。

nodeを起動します。

node app.js

起動したら「http://localhost:3000」にアクセスしましょう。
以下のような画面が表示されます。

適当にデータを送信してみましょう。

ブラウザを更新したり、新しく開いた際に前回入力した値が表示されるようになっています。

今回はmongoDBを利用することでデータの永続化を簡単に行えるやりかたでした。