/** * App客户端。 */ "use strict"; let RedisClient = require('../../repository/redis/redis.client'); let RedisModel = require('./../redis.model'); let AppStatusRepo = require('../../repository/mysql/app.status.repo'); let ModelUtil = require('../../util/model.util'); let log = require("../../util/log.js"); let pusher = require('../push/pusher'); let redisConn = RedisClient.redisClient().connection; const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES; const REDIS_KEYS = require('../../include/commons').REDIS_KEYS; const PLATFORMS = require('../../include/commons').PLATFORM; class AppClient extends RedisModel { constructor() { super(); } /** * 更新客户端App状态。 * * @param userId * @param appInBg * @param handler */ updateAppStatus(userId, appInBg, handler) { let self = this; let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserAppStatus, userId); redisConn.hgetAsync(userStatusKey, 'app_in_bg').then(function (res) { if (res !== null) { redisConn.hsetAsync(userStatusKey, 'app_in_bg', appInBg ? 1 : 0).then(function (res) { if (handler) { handler(null, true); } else { ModelUtil.emitOK(self.eventEmitter, {}); } }); } else { if (handler) { handler(null, true); } else { ModelUtil.emitDataNotFound(self.eventEmitter, {"message": "User is offline, unable to update app status."}); } } }); } /** * 获取用户App端状态。若Redis中找不到,则从MySQL中查找。 * * @param userId * @param handler */ static getAppStatus(userId, handler) { let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserAppStatus, userId); redisConn.hgetallAsync(userStatusKey) .then(function (res) { if (res) { handler(null, res); } else { AppStatusRepo.findOne(userId, function (err, res) { if (err) throw err; let userStatus = null; if (res.length > 0) { userStatus = { platform: res[0].platform, device_token: res[0].device_token, client_id: res[0].client_id, app_in_bg: res[0].app_in_bg == 1, last_login_time: res[0].last_login_time } } handler(null, userStatus); }); } }) .catch(function (err) { handler(err, null); }); } /** * 向App端推送消息。指令性消息不推。 * * @param targetId * @param message * @param sessionType */ static sendNotification(targetId, message, sessionType) { if (message.content_type == CONTENT_TYPES.PlainText || message.content_type == CONTENT_TYPES.Image || message.content_type == CONTENT_TYPES.Audio|| message.content_type == CONTENT_TYPES.Video) { AppClient.getAppStatus(targetId, function (err, userStatus) { if (err) { ModelUtil.logError("Get user app status failed", err); return; } if (!userStatus) { log.warn("User's app status is not found, user id: " + targetId + ", maybe user never login yet or logout?"); return; } let tipMessage = CONTENT_TYPES.typeToDescription(parseInt(message.content_type), "您有一条新消息") || message.content; let customData = { session_id: '' || message.session_id, session_type: sessionType, topic_id: '' || message.topic_id, from: '' || message.sender_id, data: message.content, business_type: message.business_type || 1 }; if (userStatus.platform == PLATFORMS.iOS) { pusher.pushToSingleViaAPN(tipMessage, customData, message.contentType, userStatus.device_token, function (err, res) { if (err) { ModelUtil.logError("Send notification via APN failed", err); } else { log.info("Send notification via APN succeed: ", JSON.stringify(res)); } }); } else if (userStatus.platform == PLATFORMS.Android) { let title = '新消息'; pusher.pushToSingleViaAndroid(title, tipMessage, customData, userStatus.client_id, userStatus.app_in_bg, function (err, res) { if (err) { ModelUtil.logError("Send notification via Android failed", err); } else { log.info("Send notification via Android succeed: ", JSON.stringify(res)); } }); } }); } } } // Expose class module.exports = AppClient;