なんだかよく分からないけどgetやpostのルート指定してるのにタイムアウトになる
var express = require('express'); var app = express(); app.get('/api/party.json', function(req, res){ res.end(); });
res.end()を指定しないとタイムアウトになります。
expressでのgetの取得方法
function(req, res){ req.query; //getのデータがオブジェクトの状態で入っている };
MongoDBと連携したい
MongoDBのインストールについてはこちら
mongoose以外の方法もあります→GitHub - christkv/node-mongodb-native: Mongo DB Native NodeJS Driver
var mongoose = require('mongoose'); var db = mongoose.createConnection('mongodb://localhost/DB名'); var schema = new mongoose.Schema({ name:String, text:String }); module.exports = db.model('コレクション名', schema);
- mongooseをnpmで入れる
- DB名のところでこのアプリで使うDB名を決める。
- new mongoose.Schemaで型を指定する。
- db.modelでコレクション名指定
db.modelで生成されたオブジェクトにキーを追加すると使用時にエラーになる可能性があるので注意。
use DB名 db.コレクション名s.find()
mongoコマンドでアクセスする時は「DB名.コレクション名s」になる。コレクション名の後ろに「s」がつくことに注意。
var Db = require('上のコード'); //保存 var db = new Db({hoge:''}); db.save(); //更新 //第一引数がSQLのWHERE、第二引数がSET、第三引数がオプション。オプションについてはよく分かっていない。 //第二引数に{$set:{}}を使わない場合、省略された値は消えてしまう模様。 //また、_idが第二引数に使われているとエラーになるかもしれないので注意 Db.update({'_id':ObjectId('')}, {hoge:'huga'}, {malti:false}); //全件取得 Db.find(function(error, items){ //itemsに結果が入る }); //値を限定して取得 Db.find({hoge:''}, function(error, items){}); //特定のキー名のみからデータを取得。SELECT hoge, ahu FROM Db WHERE hoge = '';みたいな形式 Db.find({hoge:''}, '_id huga ahu', function(){error, items}); //MongoDBの一意IDから取得 Db.findById('MongoDBが生成した一意id', function(error, item){}); //全件削除 Db.remove(function(){});
一癖あるよね。
findでの比較:MongoDBの集計機能が便利過ぎて泣けてくるお話し - Y's note
ありがたや。
参考:node.js から MongoDB にアクセス (Mongoose の紹介) - KrdLab's blog
配列に格納され、かつオブジェクトに入っている_idを元にデータを取得したい
var mongoose = require('mongoose'); var db = mongoose.createConnection('mongodb://localhost/db'); var schemaA = new mongoose.Schema({}); var schemaB = new mongoose.Schema({ name:String, join:[ { 'id':{type: mongoose.Schema.Types.ObjectId, ref: 'A'} } ] }); var dbA = db.model('A', schemaA);//1 var dbB = db.model('B', schemaB);
複数のコレクションを使う時、_idでドキュメントを保存し、必要に応じてデータを取得したい時があると思います。そのような時のためにこれをメモします。
まず前提条件なのですが、上記コードの1の部分のように、db変数に格納された値に、あらかじめ複数のコレクションのスキーマ情報を食べさせておかなければなりません。これを行わないと、上手く動作しません。mongooseでデータを操作する処理をコレクション単位で分けて書いている場合、注意が必要です。
複数の_idを配列で格納するのは、上記例のjoinの部分です。typeで格納したいものが_idである事を明示し、refでどのスキーマの_idであるかを識別します。もしdb.modelでAというスキーマを指定していない場合、実行時に「MissingSchemaError: Schema hasn't been registered for model」というエラーが発生します。
dbB.findOne({_id:'Aコレクションの_id'}) .populate('join.id') .exec(function(error, joins){ joins;//{id:{/*スキーマAに格納された情報*/}} });
前提条件として、dbAに値を格納し、dbBにのjoinに配列でdbA._idを保存した状態であるとします。
populateでjoin.idと指定すると、join[].idをdbA._idからdbAに格納された実際の値に置換を行います。
参考:
If I never try, I'll never know: Node.jsが面白い件⑥ MongoDBで遊ぶ 〜Mongoose編その③:サブドキュメントとリファレンス〜
Mongoose v5.5.1: Query Population
node.js - Mongoose populate within an object? - Stack Overflow
mongooseでfindを行おうとすると「TypeError: Object #\
mongooseで生成されたオブジェクトにキーを追加すると発生する。
キーを追加しない形にすればOK。
findなどで使える比較演算
演算子名 | 用途 | 例 | 参考 |
$ne | not equalの略称。それと一致しないものを返す | {$ne:_id} | MongoDB not equal to - Stack Overflow |
$or | 配列で条件を指定する。_idに対して$orは使えないらしい(Error: Can't use $or with ObjectId.) | {$or:[{item:'どうのつるぎ'}, {item:'てつのつるぎ'}]} | $and — MongoDB Manual |
$set | 値の更新。update時に$setを使用した場合、キー名が一致するものを更新し、その他のキーには何も行わない | {$set:{item:'はがねのつるぎ'}} |
socket.io
npm install socket.io
httpでlistenしたものをsocket.ioに渡さないとエラーになる。
サーバ側
var express = require("express"); var socketIO = require('socket.io'); var app = express(); app.use(express.static(__dirname + '/public')); app.get("/", function(req, res){ res.send("test"); }); var server = require('http').createServer(app); server.listen(3000, function(){ console.log("start"); }); var io = socketIO.listen(server); io.sockets.on("connection", function(socket){ console.log("connection"); socket.on("message", function(data){ console.log("message"); }); });
クライアント側。
/socket.io/socket.io.jsをクライアント側に読み込ませることで、WebSocketが使用可能になる。
/socket.io/socket.io.jsはsocket.ioをインストールした時点で暗黙的に使用可能のようだ。
<button /> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect("ws://サーバのアドレス"); socket.on("connect", function(){ console.log("接続"); }); socket.on("message", function(msg){ console.log("サーバからのデータ受け取り"); }); $("button").click(function(){ //サーバへのデータ送信 socket.send(JSON.stringify({ "test":"test" })); }); </script>
disconnectイベント
var express = require("express"); var socketIO = require('socket.io'); var app = express(); app.use(express.static(__dirname + '/public')); app.get("/", function(req, res){ res.send("test"); }); var server = require('http').createServer(app); server.listen(3000, function(){ console.log("start"); }); var io = socketIO.listen(server); io.sockets.on("connection", function(socket){ console.log("connection"); //disconnectイベントはconnectionイベントの第一引数で設定しないといけない socket.on("disconnect", function(data){ console.log("message"); }); });
参考:
【初心者向け】node.js(0.10x) + socket.io(0.9x)のサンプルプログラム - 大人になったら肺呼吸
WebSocket 事始め by Node.js + Socket.IO - Qiita
http://mawatari.jp/archives/make-a-chat-application-in-node-js-and-websocket-io
セッションの共有
普通に使うとWebSocketのセッションとhttpのセッションは共有されない。
socket.io@1.0.3
express-session@1.2.1
express@4.4.0
cookie-parser@1.1.0
var express = require('express'); var cookieParser = require('cookie-parser'); var session = require("express-session"); var http = require('http'); var app = express(); //セッションを使う時はcookie-parserは必須 app.use(cookieParser()); const COOKIE = { //ここでインスタンスを生成するのが大事です! store: new session.MemoryStore, secret: 'SRX', cookie: { httpOnly: false } }; app.use(session(COOKIE)); var server = http.createServer(app); var io = require('socket.io').listen(server); io.on("connection", function(socket){ console.log("connection"); socket.on("message", function(data){ //ここでクッキー情報を取得 var cookie = require('cookie').parse(socket.request.headers.cookie); //何故かconnect.sidの値をそのまま使えないので、必要のない文字列を削る。 cookie = cookie['connect.sid'].match(/s:([^.]*)\./)[1]; //また、storeはappに食わせたものを使わないとgetは正しく動かない。 COOKIE.store.get(cookie, function(error, session){ //セッション取得! console.log(session); }); }); });
参考:
Socket.IO と Express でセッションの共有 - Block Rockin’ Codes
GitHub - expressjs/session: Simple session middleware for Express
require("express-session").MemoryStore
store.get("expressが管理しているクッキーの情報", function(session){});でセッション情報を取得出来る。
が、取得されたデータを書き換える場合はstore.set("expressが管理しているクッキーの情報", session);としないと上書き保存はなされない。
jsの原理からすれば当然なのかもしれないが、ハマると結構大変。