Browse Source

修复消息发送时时间戳使用字符串的问题;topics表增加description字段

Sand 8 years ago
parent
commit
0687a68305

+ 14 - 3
src/server/models/messages/messages.js

@ -11,6 +11,7 @@ let redis = RedisClient.redisClient().connection;
let log = require('../../util/log.js');
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
var ObjectUtil = require("../../util/object.util.js");
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
@ -56,7 +57,7 @@ class Messages extends RedisModel {
    }
    /**
     * 将消息保存至REDIS,并更新会话的最后状态。也会清理会话的过期消息。
     * 将消息保存至REDIS,并更新会话的最后状态,清理会话的过期消息。
     *
     * @param messageId
     * @param sessionId
@ -67,9 +68,19 @@ class Messages extends RedisModel {
        let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
        let messageKey = RedisModel.makeRedisKey(REDIS_KEYS.Messages, sessionId);
        let messageTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
        let msgJson = {
            id: message.id,
            sender_id: message.sender_id,
            sender_name: message.sender_name,
            timestamp: ObjectUtil.timestampToLong(message.timestamp),
            content_type: message.content_type,
            content: message.content
        };
        redis.multi()
            .hset(messageKey, messageId, JSON.stringify(message))
            .zadd(messageTimestampKey, message.timestamp.getTime(), messageId)
            .hset(messageKey, messageId, JSON.stringify(msgJson))               // 保存消息
            .zadd(messageTimestampKey, message.timestamp.getTime(), messageId)  // 保存消息时间
            .execAsync()
            .then(function (res) {
                Messages.updateLastContent(sessionKey, sessionType, null, message);

+ 106 - 99
src/server/models/user/users.js

@ -204,118 +204,125 @@ class Users extends RedisModel {
                // cache sessions, participants, topics, messages
                function (callback) {
                    SessionRepo.findAll(userId, function (err, sessions) {
                        if(err){
                        if (err) {
                            ModelUtil.emitError(self.eventEmitter, err.message);
                            return;
                        }
                        sessions.forEach(function (session) {
                            let redisSession = [
                                "id", session.id,
                                "name", session.name,
                                "type", session.type,
                                "last_sender_id", session.last_sender_id == null ? "" : session.last_sender_id,
                                "last_sender_name", session.last_sender_name == null ? "" : session.last_sender_name,
                                "last_content_type", session.last_content_type == null ? "" : session.last_content_type,
                                "last_content", session.last_content == null ? "" : session.last_content,
                                "last_message_time", session.last_message_time == null ? "" : session.last_message_time,
                                "createDate", ObjectUtil.timestampToLong(session.create_date),
                            ];
                            (function (sessionId, userId) {
                                // cache sessions
                                redisConn.multi()
                                    .zadd(REDIS_KEYS.Sessions, lastLoginTime.getTime(), sessionId)                                           // 会话的最后活动时间设置为此用户的登录时间
                                    .zadd(RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId), lastLoginTime.getTime(), sessionId)      // 会话的最后活动时间设置为此用户的登录时间
                                    .hmset(RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId), redisSession)
                                    .execAsync()
                                    .then(function (res) {
                                        // cache participants
                                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                                        let sessionParticipantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                                        ParticipantRepo.findParticipants(sessionId, function (err, participants) {
                                            if (err) {
                                                ModelUtil.emitError(self.eventEmitter, err.message);
                                                return;
                                            }
                                            participants.forEach(function (participant) {
                                                let participantId = participant.participant_id;
                                                let participantRole = participant.participant_role;
                                                let score = ObjectUtil.timestampToLong(participant.last_fetch_time);
                                                redisConn.multi()
                                                    .zadd(sessionParticipantsKey, score, participantId)
                                                    .hset(sessionParticipantsRoleKey, participantRole, participantId)
                                                    .execAsync().then(function (res) {
                            redisConn.zscore(REDIS_KEYS.Sessions, session.id, function (err, res) {
                                // 已经缓存过的会话不再缓存
                                if(res != null) return;
                                (function (sessionId, userId) {
                                    let redisSession = [
                                        "id", session.id,
                                        "name", session.name,
                                        "type", session.type,
                                        "last_sender_id", session.last_sender_id == null ? "" : session.last_sender_id,
                                        "last_sender_name", session.last_sender_name == null ? "" : session.last_sender_name,
                                        "last_content_type", session.last_content_type == null ? "" : session.last_content_type,
                                        "last_content", session.last_content == null ? "" : session.last_content,
                                        "last_message_time", session.last_message_time == null ? "" : session.last_message_time,
                                        "create_date", ObjectUtil.timestampToLong(session.create_date),
                                    ];
                                    // cache sessions
                                    redisConn.multi()
                                        .zadd(REDIS_KEYS.Sessions, lastLoginTime.getTime(), sessionId)                                           // 会话的最后活动时间设置为此用户的登录时间
                                        .zadd(RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId), lastLoginTime.getTime(), sessionId)      // 会话的最后活动时间设置为此用户的登录时间
                                        .hmset(RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId), redisSession)
                                        .execAsync()
                                        .then(function (res) {
                                            // cache participants
                                            let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                                            let sessionParticipantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                                            ParticipantRepo.findParticipants(sessionId, function (err, participants) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                let multi = redisConn.multi();
                                                participants.forEach(function (participant) {
                                                    let participantId = participant.participant_id;
                                                    let participantRole = participant.participant_role;
                                                    let score = ObjectUtil.timestampToLong(participant.last_fetch_time);
                                                    multi = multi.zadd(sessionParticipantsKey, score, participantId)
                                                        .hset(sessionParticipantsRoleKey, participantId, participantRole);
                                                });
                                                multi.execAsync().then(function (res) {
                                                });
                                            });
                                        });
                                        // cache messages
                                        let messagesKey = RedisModel.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                                        let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                        MessageRepo.findBySessionId(sessionId, 0, config.sessionConfig.maxMessageCount, function (err, messages) {
                                            if (err) {
                                                ModelUtil.emitError(self.eventEmitter, err.message);
                                                return;
                                            }
                                            messages.forEach(function (message) {
                                                let msgJson = {
                                                    id: message.id,
                                                    sender_id: message.sender_id,
                                                    sender_name: message.sender_name,
                                                    timestamp: ObjectUtil.timestampToLong(message.timestamp),
                                                    content_type: message.content_type,
                                                    content: message.content
                                                };
                                                redisConn.multi()
                                                    .hset(messagesKey, message.id, JSON.stringify(msgJson))
                                                    .zadd(messagesByTimestampKey, ObjectUtil.timestampToLong(message.timestamp), message.id)
                                                    .execAsync()
                                                    .then(function (res) {
                                                    });
                                            // cache messages
                                            let messagesKey = RedisModel.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                                            let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                            MessageRepo.findBySessionId(sessionId, 0, config.sessionConfig.maxMessageCount, function (err, messages) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                let multi = redisConn.multi();
                                                messages.forEach(function (message) {
                                                    let msgJson = {
                                                        id: message.id,
                                                        sender_id: message.sender_id,
                                                        sender_name: message.sender_name,
                                                        timestamp: ObjectUtil.timestampToLong(message.timestamp),
                                                        content_type: message.content_type,
                                                        content: message.content
                                                    };
                                                    multi = multi.hset(messagesKey, message.id, JSON.stringify(msgJson))
                                                        .zadd(messagesByTimestampKey, ObjectUtil.timestampToLong(message.timestamp), message.id);
                                                });
                                                multi.execAsync().then(function (res) {
                                                });
                                            });
                                        });
                                        // cache topics for MUC
                                        let topicsKey = RedisModel.makeRedisKey(REDIS_KEYS.Topics, sessionId);
                                        TopicRepo.findAllBySessionId(sessionId, function (err, topics) {
                                            if (err) {
                                                ModelUtil.emitError(self.eventEmitter, err.message);
                                                return;
                                            }
                                            topics.forEach(function (topic) {
                                                let topicKey = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topic.id);
                                                let topicId = topic.id;
                                                let name = topic.name;
                                                let createTime = ObjectUtil.timestampToLong(topic.create_time);
                                                let endBy = topic.end_by;
                                                let endTime = ObjectUtil.timestampToLong(topic.end_time);
                                                let startMessageId = topic.start_message_id;
                                                let endMessageId = topic.end_message_id;
                                                let description = topic.description;
                                                let status = topic.status;
                                                redisConn.multi()
                                                    .zadd(topicsKey, topicId)
                                                    .hmset(topicKey,
                                                        'name', name,
                                                        'session_id', sessionId,
                                                        'create_time', createTime,
                                                        'end_by', endBy,
                                                        'end_time', endTime,
                                                        'start_message_id', startMessageId,
                                                        'end_message_id', endMessageId,
                                                        'description', description,
                                                        'status', status)
                                                    .execAsync().then(function (res) {
                                            // cache topics for MUC
                                            let topicsKey = RedisModel.makeRedisKey(REDIS_KEYS.Topics, sessionId);
                                            TopicRepo.findAllBySessionId(sessionId, function (err, topics) {
                                                if (err) {
                                                    ModelUtil.emitError(self.eventEmitter, err.message);
                                                    return;
                                                }
                                                topics.forEach(function (topic) {
                                                    let topicKey = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topic.id);
                                                    let topicId = topic.id;
                                                    let name = topic.name;
                                                    let createTime = ObjectUtil.timestampToLong(topic.create_time);
                                                    let endBy = topic.end_by;
                                                    let endTime = ObjectUtil.timestampToLong(topic.end_time);
                                                    let startMessageId = topic.start_message_id;
                                                    let endMessageId = topic.end_message_id;
                                                    let description = topic.description;
                                                    let status = topic.status;
                                                    redisConn.multi()
                                                        .zadd(topicsKey, topicId)
                                                        .hmset(topicKey,
                                                            'name', name,
                                                            'session_id', sessionId,
                                                            'create_time', createTime,
                                                            'end_by', endBy,
                                                            'end_time', endTime,
                                                            'start_message_id', startMessageId,
                                                            'end_message_id', endMessageId,
                                                            'description', description,
                                                            'status', status)
                                                        .execAsync().then(function (res) {
                                                    });
                                                });
                                            });
                                        });
                                    });
                            })(session.id, userId);
                                })(session.id, userId);
                            });
                        });
                    });

+ 4 - 3
src/server/repository/mysql/message.repo.js

@ -24,8 +24,8 @@ class MessageRepo {
     * @param handler
     */
    static findBySessionId(sessionId, page, size, handler) {
        if (page <= 0) {
            page = 1;
        if (page < 0) {
            page = 0;
        }
        SessionRepo.findOne(sessionId, function (err, res) {
@ -47,7 +47,8 @@ class MessageRepo {
                    MessageTable = DB_TABLES.GroupMessages;
                }
                let sql = "select id, session_id, sender_id, sender_name, content_type, content, timestamp from " + MessageTable + " w where w.session_id = ? limit ?, ?";
                let sql = "select id, session_id, sender_id, sender_name, content_type, content, timestamp from " +
                    MessageTable + " w where w.session_id = ? order by w.id limit ?, ?";
                ImDb.execQuery({
                    "sql": sql,
                    "args": [sessionId, page, size],

+ 1 - 1
src/server/repository/mysql/participant.repo.js

@ -19,7 +19,7 @@ class ParticipantRepo {
     * @param handler
     */
    static findParticipants(sessionId, handler) {
        let sql = "select participant_id, participant_role, last_fetch_time from participants where session_id = ? ";
        let sql = "select participant_id, participant_role, last_fetch_time from participants where session_id = ? order by participant_id";
        ImDb.execQuery({
            "sql": sql,

+ 1 - 1
src/server/repository/mysql/topic.repo.js

@ -36,7 +36,7 @@ class TopicsRepo {
     */
    static findAllBySessionId(sessionId, handler){
        let sql = "select id, session_id, name, create_time, end_by, end_time," +
            " start_message_id, end_message_id, description, status from topics where session_id = ?";
            " start_message_id, end_message_id, description, status from topics where session_id = ? order by id";
        ImDb.execQuery({
            sql: sql,

+ 1 - 0
src/server/resources/schema/ichat_1.2.8_table_schema.sql

@ -93,6 +93,7 @@ CREATE TABLE `topics`
	`start_message_id` INTEGER COMMENT '消息起始ID',
	`end_message_id` INTEGER COMMENT '消息结束ID',
	`status` INT COMMENT '议题状态,0新建,1已回复未结束,10结束',
	`description` VARCHAR(1024) COMMENT '议题描述',
	CONSTRAINT `PK_topics` PRIMARY KEY (`id`)
) COMMENT='议题,仅MUC模式使用。'
;

+ 2 - 1
src/server/resources/schema/temp.sql

@ -1,6 +1,6 @@
/* ---------------------------------------------------- */
/*  Generated by Enterprise Architect Version 12.0 		*/
/*  Created On : 05-Jan-2017 8:54:40 AM 				*/
/*  Created On : 05-Jan-2017 9:17:28 AM 				*/
/*  DBMS       : MySql 						*/
/* ---------------------------------------------------- */
@ -24,6 +24,7 @@ CREATE TABLE `topics`
	`start_message_id` INTEGER COMMENT '消息起始ID',
	`end_message_id` INTEGER COMMENT '消息结束ID',
	`status` INT COMMENT '议题状态,0新建,1已回复未结束,10结束',
	`description` VARCHAR(1024) COMMENT '议题描述',
	CONSTRAINT `PK_topics` PRIMARY KEY (`id`)
) COMMENT='议题,仅MUC模式使用。'
;

+ 13 - 3
test/client/im.client.session.p2p.Test.js

@ -112,9 +112,9 @@ describe("Session P2P", function () {
        });
    });
    // 获取并发送消息: B -> A
    describe("Send message from B to A", function () {
        it("every message must be ok", function (done) {
    // 获取会话列表及消息数
    describe("Get sessions and unread messages for B", function () {
        it("every operation must be ok", function (done) {
            imClient.Sessions.getSessionsWithDoctor(TD.P2P.DoctorB.id, 0, 10,
                function (sessions) {
                    let isPass = false;
@ -141,6 +141,10 @@ describe("Session P2P", function () {
                    imClient.Sessions.getSessionUnreadMessages(TD.SessionId, TD.P2P.DoctorB.id,
                        function (data) {
                            assert.strictEqual(data.length, TD.UnreadMessageCount, "Get session unread messages failed.");
                            data.forEach(function (message) {
                                console.log(message);
                            });
                            done();
                        },
                        function (xhr, status, error) {
@ -156,6 +160,12 @@ describe("Session P2P", function () {
        });
    });
    // 发送消息: B -> A
    describe("Send message from B to A", function () {
        it("every message must be ok", function (done) {
        });
    });
    // 退出
    describe("User logout", function () {
        it("all user must be success", function (done) {