statusService.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var DefaultStatusManager = require('../manager/statusManager');
  2. var utils = require('../util/utils');
  3. var util = require('util');
  4. var countDownLatch = require('../util/countDownLatch');
  5. var logger = require('pomelo-logger').getLogger(__filename);
  6. var ST_INITED = 0;
  7. var ST_STARTED = 1;
  8. var ST_CLOSED = 2;
  9. var StatusService = function(app, opts) {
  10. this.app = app;
  11. this.opts = opts || {};
  12. this.cleanOnStartUp = opts.cleanOnStartUp;
  13. this.manager = getStatusManager(app, opts);
  14. this.state = ST_INITED;
  15. };
  16. module.exports = StatusService;
  17. StatusService.prototype.start = function(cb) {
  18. if(this.state !== ST_INITED) {
  19. utils.invokeCallback(cb, new Error('invalid state'));
  20. return;
  21. }
  22. if(typeof this.manager.start === 'function') {
  23. var self = this;
  24. this.manager.start(function(err) {
  25. if(!err) {
  26. self.state = ST_STARTED;
  27. }
  28. if(!!self.cleanOnStartUp) {
  29. self.manager.clean(function(err) {
  30. utils.invokeCallback(cb, err);
  31. });
  32. } else {
  33. utils.invokeCallback(cb, err);
  34. }
  35. });
  36. } else {
  37. process.nextTick(function() {
  38. utils.invokeCallback(cb);
  39. });
  40. }
  41. };
  42. StatusService.prototype.stop = function(force, cb) {
  43. this.state = ST_CLOSED;
  44. if(typeof this.manager.stop === 'function') {
  45. this.manager.stop(force, cb);
  46. } else {
  47. process.nextTick(function() {
  48. utils.invokeCallback(cb);
  49. });
  50. }
  51. };
  52. StatusService.prototype.add = function(uid, sid, cb) {
  53. if(this.state !== ST_STARTED) {
  54. utils.invokeCallback(cb, new Error('invalid state'));
  55. return;
  56. }
  57. this.manager.add(uid, sid, cb);
  58. };
  59. StatusService.prototype.leave = function(uid, sid, cb) {
  60. if(this.state !== ST_STARTED) {
  61. utils.invokeCallback(cb, new Error('invalid state'));
  62. return;
  63. }
  64. this.manager.leave(uid, sid, cb);
  65. };
  66. StatusService.prototype.getSidsByUid = function(uid, cb) {
  67. if(this.state !== ST_STARTED) {
  68. utils.invokeCallback(cb, new Error('invalid state'));
  69. return;
  70. }
  71. this.manager.getSidsByUid(uid, cb);
  72. };
  73. StatusService.prototype.getStatusByUid = function(uid, cb) {
  74. if(this.state !== ST_STARTED) {
  75. utils.invokeCallback(cb, new Error('invalid state'));
  76. return;
  77. }
  78. this.manager.getSidsByUid(uid, function(err, list) {
  79. if (!!err) {
  80. utils.invokeCallback(cb, new Error(util.format('failed to get serverIds by uid: [%s], err: %j', uid, err.stack)), null);
  81. return;
  82. }
  83. var status = (list !== undefined && list.length >= 1)
  84. ? true // online
  85. : false; // offline
  86. utils.invokeCallback(cb, null, status);
  87. });
  88. };
  89. StatusService.prototype.getStatusByUids = function(uids, cb) {
  90. if(this.state !== ST_STARTED) {
  91. utils.invokeCallback(cb, new Error('invalid state'));
  92. return;
  93. }
  94. this.manager.getSidsByUids(uids, function(err, replies) {
  95. if (!!err) {
  96. utils.invokeCallback(cb, new Error(util.format('failed to get serverIds by uids, err: %j', err.stack)), null);
  97. return;
  98. }
  99. var statuses = {};
  100. for (var i=0; i<uids.length; i++) {
  101. statuses[uids[i]] = (replies[i] == 1)
  102. ? true // online
  103. : false; // offline
  104. }
  105. utils.invokeCallback(cb, null, statuses);
  106. });
  107. };
  108. StatusService.prototype.pushByUids = function(uids, route, msg, cb) {
  109. if(this.state !== ST_STARTED) {
  110. utils.invokeCallback(cb, new Error('invalid state'));
  111. return;
  112. }
  113. var channelService = this.app.get('channelService');
  114. var successFlag = false;
  115. var count = utils.size(uids);
  116. var records = [];
  117. var latch = countDownLatch.createCountDownLatch(count, function(){
  118. if(!successFlag) {
  119. utils.invokeCallback(cb, new Error(util.format('failed to get sids for uids: %j', uids)), null);
  120. return;
  121. }
  122. else {
  123. if(records != null && records.length != 0){
  124. channelService.pushMessageByUids(route, msg, records, cb);
  125. }else{
  126. utils.invokeCallback(cb, null, null);
  127. }
  128. }
  129. });
  130. for(var i=0; i< uids.length; i++) {
  131. (function (self, arg) {
  132. self.getSidsByUid(uids[arg], function (err, list) {
  133. if (!!err) {
  134. utils.invokeCallback(cb, new Error(util.format('failed to get serverIds by uid: [%s], err: %j', uids[arg], err.stack)), null);
  135. return;
  136. }
  137. for (var j = 0, l = list.length; j < l; j++) {
  138. records.push({uid: uids[arg], sid: list[j]});
  139. }
  140. successFlag = true;
  141. latch.done();
  142. })
  143. })(this, i);
  144. }
  145. };
  146. var getStatusManager = function(app, opts) {
  147. var manager;
  148. if(typeof opts.statusManager === 'function') {
  149. manager = opts.statusManager(app, opts);
  150. } else {
  151. manager = opts.statusManager;
  152. }
  153. if(!manager) {
  154. manager = new DefaultStatusManager(app, opts);
  155. }
  156. return manager;
  157. };