app.client.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * App客户端。
  3. */
  4. "use strict";
  5. let RedisClient = require('../../repository/redis/redis.client');
  6. let RedisModel = require('./../redis.model');
  7. let AppStatusRepo = require('../../repository/mysql/app.status.repo');
  8. let ModelUtil = require('../../util/model.util');
  9. let log = require("../../util/log.js");
  10. let pusher = require('../push/pusher');
  11. let redisConn = RedisClient.redisClient().connection;
  12. const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES;
  13. const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
  14. const PLATFORMS = require('../../include/commons').PLATFORM;
  15. class AppClient extends RedisModel {
  16. constructor() {
  17. super();
  18. }
  19. /**
  20. * 更新客户端App状态。
  21. *
  22. * @param userId
  23. * @param appInBg
  24. * @param handler
  25. */
  26. updateAppStatus(userId, appInBg, handler) {
  27. let self = this;
  28. let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserAppStatus, userId);
  29. redisConn.hgetAsync(userStatusKey, 'app_in_bg').then(function (res) {
  30. if (res !== null) {
  31. redisConn.hsetAsync(userStatusKey, 'app_in_bg', appInBg ? 1 : 0).then(function (res) {
  32. if (handler) {
  33. handler(null, true);
  34. } else {
  35. ModelUtil.emitOK(self.eventEmitter, {});
  36. }
  37. });
  38. } else {
  39. if (handler) {
  40. handler(null, true);
  41. } else {
  42. ModelUtil.emitDataNotFound(self.eventEmitter, {"message": "User is offline, unable to update app status."});
  43. }
  44. }
  45. });
  46. }
  47. /**
  48. * 获取用户App端状态。若Redis中找不到,则从MySQL中查找。
  49. *
  50. * @param userId
  51. * @param handler
  52. */
  53. static getAppStatus(userId, handler) {
  54. let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserAppStatus, userId);
  55. redisConn.hgetallAsync(userStatusKey)
  56. .then(function (res) {
  57. if (res != null) {
  58. handler(null, res);
  59. } else {
  60. AppStatusRepo.findOne(userId, function (err, res) {
  61. if (err) throw err;
  62. let userStatus = null;
  63. if (res.length > 0) {
  64. userStatus = {
  65. platform: res[0].platform,
  66. token: res[0].token,
  67. client_id: res[0].client_id,
  68. app_in_bg: res[0].app_in_bg === 1,
  69. last_login_time: res[0].last_login_time
  70. }
  71. }
  72. handler(null, userStatus);
  73. });
  74. }
  75. })
  76. .catch(function (err) {
  77. handler(err, null);
  78. });
  79. }
  80. /**
  81. * 向App端推送消息。
  82. *
  83. * @param targetId
  84. * @param message
  85. * @param sessionType
  86. */
  87. static sendNotification(targetId, message, sessionType) {
  88. AppClient.getAppStatus(targetId, function (err, userStatus) {
  89. if (err) {
  90. ModelUtil.logError("Get user app status failed", err);
  91. return;
  92. }
  93. if(!userStatus){
  94. log.warn("userStatus is not online!");
  95. return;
  96. }
  97. let tipMessage = CONTENT_TYPES.typeToDescription(parseInt(message.content_type), "您有一条新消息") || message.content;
  98. let customData = {
  99. session_id: '' || message.session_id,
  100. session_type: sessionType,
  101. topic_id: '' || message.topic_id,
  102. from: '' || message.sender_id,
  103. data: message.content,
  104. business_type:message.business_type||1
  105. };
  106. if (userStatus.platform == PLATFORMS.iOS) {
  107. pusher.pushToSingleViaAPN(tipMessage, customData,message.contentType, userStatus.token, function (err, res) {
  108. if (err) {
  109. ModelUtil.logError("Send notification via APN failed", err);
  110. } else {
  111. log.info("Send notification via APN succeed: ", JSON.stringify(res));
  112. }
  113. });
  114. } else if (userStatus.platform == PLATFORMS.Android) {
  115. let title = '新消息';
  116. pusher.pushToSingleViaAndroid(title, tipMessage, customData, userStatus.client_id, userStatus.app_in_bg, function (err, res) {
  117. if (err) {
  118. ModelUtil.logError("Send notification via Android failed", err);
  119. } else {
  120. log.info("Send notification via Android succeed: ", JSON.stringify(res));
  121. }
  122. });
  123. }
  124. });
  125. }
  126. }
  127. // Expose class
  128. module.exports = AppClient;