node.js redis同期取値bluebird async await promisifyAll
1.redisライブラリのインストール
npm install --save redis
2. ../../.../config.js
3. Cache.js
Usage:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
もう一つの方法bluebird
使用するライブラリ:
http://bluebirdjs.com/docs/getting-started.html
* ./config/cache.js
redis構成
* ./providers/Redis.js
キーコード:
promisifyAllの後にクライアントに値を再割り当てします
* ./app/controllers/Middleware.js
ブルーバードのPromisifyAllを使ったのでgetメソッドによってgetAsyncができました
await cache.get(key, function(err, res) {
//...
})
ここではboolタイプを返し、所望のredisではなく結果を返します.
const res=await cacheに変更します.getAsync( key );
これでresはredisの戻り結果です
* router.js
* ./app/controllers/UserController.js
mongodb:
* ./config/db.js
* ./app/models/mongoose.js
* ./app/models/Users.js
npm install --save redis
2. ../../.../config.js
module.exports = {
// ...
redis: {
host: "172.16.0.224",
port: 6379,
options: {
password: "myredispassword",
timeout: 3000
}
},
spam: {
limit: 3,
seconds: 60,
},
// ...
}
3. Cache.js
const redis = require("redis");
const config = require("../config/config");
let c = config.redis,
client = redis.createClient(c.port, c.host, c.options);
client.on("error",function(err){
console.log(err);
});
function Cache() {}
let text = async(key)=>{
let doc = await new Promise( (resolve) => {
client.get(key,function(err, res){
return resolve(res);
});
});
return JSON.parse(doc);
};
Cache.set = function(key, value) {
value = JSON.stringify(value);
return client.set(key, value, function(err){
if (err) {
console.error(err);
}
});
};
Cache.get = async(key)=>{
return await text(key);
};
Cache.expire = function(key, time) {
return client.expire(key, time);
};
module.exports = Cache;
Usage:
// begin
let ip = Client.getIP(req);
let key = "mail:" + ip;
let ans = await Cache.get(key);
let count = 0;
if (ans) {
logger.debug(ans);
count = parseInt(ans);
}
count++;
Cache.set(key, count);
//
Cache.expire(key, config.spam.seconds);
if (count > config.spam.limit) {
res.json({
code: 16,
data: count,
message: " "
});
return;
}
// end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
もう一つの方法bluebird
使用するライブラリ:
http://bluebirdjs.com/docs/getting-started.html
* ./config/cache.js
redis構成
module.exports = function() {
return {
session: {
host: "172.16.0.224",
port: 6379,
option: {
password: "Mzh123",
db: 0,
connect_timeout: 500,
}
},
app: {
host: "172.16.0.224",
port: 6379,
option: {
password: "Mzh123",
db: 1,
connect_timeout: 500,
}
}
};
};
* ./providers/Redis.js
const redis = require("redis");
const cacheConfig = require("../config/cache")();
const bluebird = require('bluebird');
function Redis() {}
/**
*
* @type {{session: null|RedisClient}}
* @private
*/
Redis._connection = {
"session": undefined,
"app": undefined,
};
Redis.getConnection = function(name) {
name = name || "session";
if ( Redis._connection[name] ) {
return Redis._connection[name];
}
let opt = cacheConfig[ name ];
let client = redis.createClient(opt.port, opt.host, opt.option);
client.on('connect', function() {
console.log('Redis connected.')
});
client = bluebird.promisifyAll(client);
Redis._connection[name] = client;
return Redis._connection[name];
};
module.exports = Redis;
キーコード:
client = bluebird.promisifyAll(client);
promisifyAllの後にクライアントに値を再割り当てします
* ./app/controllers/Middleware.js
'use strict';
var jwt = require('jsonwebtoken');
// var koaJwt = require('koa-jwt');
var constants = require('../../config/const');
var Redis = require('../../providers/Redis');
function Middleware() {}
Middleware.hasBody = async (ctx, next) => {
let body = ctx.request.body || {};
console.log(body);
if (Object.keys(body).length === 0) {
ctx.body = {
code: 2,
err: ' '
};
return next
}
await next()
};
// token
Middleware.hasToken = async (ctx, next) => {
var accessToken = ctx.headers.token;
if (!accessToken) {
accessToken = ctx.request.body['token'];
}
if (!accessToken) {
ctx.body = {
code: 4,
data: null,
message: 'Token missing'
};
return next
}
// :{"userid":"5cc7f30396e85920c0c5b885","username":"mingzhanghui","iat":1556609542,"exp":1556609602}
let c = constants();
let tokenContext = jwt.decode(accessToken);
/**
* @type RedisClient
*/
let cache = Redis.getConnection('session');
let key = c.session_prefix + tokenContext.userid;
console.log(key);
// if (+new Date() >= c.exp * 1000) {
const res = await cache.getAsync( key );
if (! res) {
ctx.body = {
code: 5,
data: null,
message: 'Token expired',
};
return
}
let sess = JSON.parse(res);
console.log(sess);
ctx.session.user = {
id: sess.userid,
name:sess.username
};
await next();
};
module.exports = Middleware;
ブルーバードのPromisifyAllを使ったのでgetメソッドによってgetAsyncができました
await cache.get(key, function(err, res) {
//...
})
ここではboolタイプを返し、所望のredisではなく結果を返します.
const res=await cacheに変更します.getAsync( key );
これでresはredisの戻り結果です
* router.js
'use strict';
const Router = require('koa-router');
const Middleware = require('./app/controllers/middleware');
const UserController = require('./app/controllers/UserController');
const TestController = require('./app/controllers/TestController');
module.exports = function(){
var router = new Router({
prefix: '' /* /api */
});
router.get('/ping', async function(ctx, next) {
ctx.body = {
"code": 0,
"data": null,
"message": "pong"
};
ctx.contentType = 'application/json';
});
// user
router.post("/users/login", Middleware.hasBody, (new UserController()).login);
// need login middleware.hasToken
router.get('/users/getInfo', Middleware.hasToken, (new UserController()).getInfo);
router.get('/users/logout', Middleware.hasToken, (new UserController()).logout);
router.post('/users/signup', Middleware.hasBody, (new UserController()).signup);
router.post('/users/update', Middleware.hasBody, (new UserController()).update);
// router.get('/users/delete', (new UserController()).delete);
// DB Interface test
router.get('/users/all', (new UserController()).all);
router.get('/test', (new TestController()).date);
return router
};
* ./app/controllers/UserController.js
/**
*
* @param ctx
* @param next
* @returns {Promise}
*/
UserController.prototype.getInfo = async function(ctx, next) {
// let token = ctx.headers.token;
let userid = ctx.session.user.id;
console.log("userid=" + userid);
if (!userid) {
ctx.body = {
code: -1,
data: null,
message: "Redis get error"
};
return;
}
await Users.findOne({"_id": userid}).exec().then(function (doc) {
if (!doc) {
ctx.body = {
code: 2,
data: doc,
message: "User not found"
};
return;
}
ctx.body = {
code:0,
data: doc,
message: "OK"
};
});
};
mongodb:
* ./config/db.js
module.exports = function() {
return {
default: 'mongodb://eclassuser:[email protected]/crm_sale'
};
};
* ./app/models/mongoose.js
"use strict";
const bluebird = require('bluebird');
const Mongoose = require('mongoose');
const dbDefaultURI = require('../../config/db.js')().default;
let mongoose = bluebird.promisifyAll(Mongoose);
let defaultMongooseConn = mongoose.createConnection(dbDefaultURI);
defaultMongooseConn.on('error', function(err) {
// logger.error(err);
console.error(err);
});
module.exports = {
mongoose: mongoose,
defaultMongooseConn: defaultMongooseConn
};
* ./app/models/Users.js
"use strict";
let m = require("./mongoose");
const mongoose = m.mongoose;
const defaultMongooseConn = m.defaultMongooseConn;
var Schema = mongoose.Schema;
var schema = new Schema({
username: {type: String, required: true},
password: {type: String},
createdAt: {type: Date, default: Date.now()},
updatedAt: {type: Date, default: Date.now()},
});
schema.index({username: 1}, {unique: true});
// Defines a pre hook for the document.
schema.pre('save', function(next) {
if (this.isNew) {
this.createdAt = this.updatedAt = Date.now()
}
else {
this.updatedAt = Date.now()
}
next()
});
var Users = defaultMongooseConn.model('users', schema);
module.exports = Users;