koa-redis.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**!
  2. * koa-redis - lib/koa-redis.js
  3. * Copyright(c) 2013
  4. * MIT Licensed
  5. *
  6. * Authors:
  7. * dead_horse <dead_horse@qq.com> (http://deadhorse.me)
  8. */
  9. 'use strict';
  10. /**
  11. * Module dependencies.
  12. */
  13. var debug = require('debug')('koa:redis');
  14. var Redis = require('redis');
  15. var EventEmitter = require('events').EventEmitter;
  16. var util = require('util');
  17. /**
  18. * Initialize redis session middleware with `opts`:
  19. *
  20. * @param {Object} options
  21. * - {Object} client redis client
  22. * - {String} host redis connect host (with out options.client)
  23. * - {Number} port redis connect port (with out options.client)
  24. * - {String} socket redis connect socket (with out options.client)
  25. * - {String} db redis db
  26. * - {String} pass redis password
  27. */
  28. var RedisStore = module.exports = function (options) {
  29. if (!(this instanceof RedisStore)) {
  30. return new RedisStore(options);
  31. }
  32. EventEmitter.call(this);
  33. options = options || {};
  34. var client;
  35. if (!options.client) {
  36. debug('Init redis with host: %s, port: %d, socket: %s',
  37. options.host || 'localhost', options.port || 6379, options.socket || '');
  38. client = Redis.createClient(options.port || options.socket,
  39. options.host, options);
  40. } else {
  41. client = options.client;
  42. }
  43. options.pass && client.auth(options.pass, function (err) {
  44. if (err) {
  45. throw err;
  46. }
  47. });
  48. if (options.db) {
  49. client.select(options.db);
  50. client.on("connect", function() {
  51. client.send_anyways = true;
  52. client.select(options.db);
  53. client.send_anyways = false;
  54. });
  55. }
  56. client.on('error', this.emit.bind(this, 'disconnect'));
  57. client.on('end', this.emit.bind(this, 'disconnect'));
  58. client.on('connect', this.emit.bind(this, 'connect'));
  59. //wrap redis
  60. this._redisClient = client;
  61. this.client = require('co-redis')(client);
  62. };
  63. util.inherits(RedisStore, EventEmitter);
  64. RedisStore.prototype.get = function *(sid) {
  65. var data = yield this.client.get(sid);
  66. debug('get session: %s', data || 'none');
  67. if (!data) {
  68. return null;
  69. }
  70. try {
  71. return JSON.parse(data.toString());
  72. } catch (err) {
  73. // ignore err
  74. debug('parse session error: %s', err.message);
  75. }
  76. };
  77. RedisStore.prototype.set = function *(sid, sess, ttl) {
  78. if (typeof ttl === 'number') {
  79. ttl = ttl / 1000;
  80. }
  81. sess = JSON.stringify(sess);
  82. if (ttl) {
  83. debug('SETEX %s %s %s', sid, ttl, sess);
  84. yield this.client.setex(sid, ttl, sess);
  85. } else {
  86. debug('SET %s %s', sid, sess);
  87. yield this.client.set(sid, sess);
  88. }
  89. debug('SET %s complete', sid);
  90. };
  91. RedisStore.prototype.destroy = function *(sid, sess) {
  92. debug('DEL %s', sid);
  93. yield this.client.del(sid);
  94. debug('DEL %s complete', sid);
  95. };