コード例 #1
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetReadState(string accesstoken, string msg_uids)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            var readstate = new Dictionary <string, dynamic>();

            if (!String.IsNullOrEmpty(msg_uids))
            {
                var msg_uid_list  = msg_uids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var redis_msgpost = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGPOST_KEY);
                redis_msgpost.Exec(db => {
                    foreach (var msg_uid in msg_uid_list)
                    {
                        var val = db.SortedSetScore($"readtime_{msg_uid}", userid);
                        if (val.HasValue)
                        {
                            readstate.Add(msg_uid.ToString(), new { readstate = 1, readtime = val.Value });
                        }
                        else
                        {
                            readstate.Add(msg_uid.ToString(), new { readstate = 0 });
                        }
                    }
                });
            }

            return(JsonContent(readstate));
        }
コード例 #2
0
        public ActionResult GetUserState(string accesstoken, string userid)
        {
            if (String.IsNullOrEmpty(userid))
            {
                throw new BusinessException("userid不能为空");
            }

            var isOnline       = false;
            var uiState        = "visible";
            var current_userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            var redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_SESSION_KEY);
            var task1 = FaceHand.Common.ThreadHelp.Start(() => {
                var imuser_usertoken = $"imuser_user_token_{userid}";
                var tokenList        = redis.Exec <RedisValue[]>(db => db.SetMembers(imuser_usertoken));
                if (tokenList != null && tokenList.Length > 0)
                {
                    //能在有效的token中找到client,只能说明在2小时内登陆过,还不能证明是当前在线的,但这是证明在线一个前提
                    var clientFlags = new List <string>()
                    {
                        ConstDefined.CLIENT_FLAG_WECHAT, ConstDefined.CLIENT_FLAG_MINIPROGRAM
                    };
                    var clientContain = false;

                    foreach (var token in tokenList)
                    {
                        var client = redis.Exec <string>(db => db.HashGet($"imuser_token_user_{token}", RedisFields.SESSION_TOKEN_CLIENTFLAG));
                        if (clientFlags.Contains(client))
                        {
                            clientContain = true;
                            break;
                        }
                    }

                    if (clientContain)
                    {
                        //在判断最后一次活动时间,如果最后一次活动在5分钟以内就表示在新,否则表示不在线
                        var lasttime = redis.Exec <RedisResult>(db => db.Execute("get", $"imuser_lastactivetime_{userid}")).AsInt();
                        if (lasttime != 0 &&
                            (DateTime.Now - lasttime.AsDateTimeFromUnixTimestamp()).TotalSeconds <= Entity.ConstDefined.LASTACTIVETIME_MAX_SECONDS * 2)
                        {
                            isOnline = true;
                        }
                    }
                }
            });
            var task2 = FaceHand.Common.ThreadHelp.Start(() => {
                var re  = redis.Exec <int>(db => db.Execute("get", $"imuser_user_clientstate_{userid}").AsInt());
                uiState = (re == 1 ? "visible" : "hidden");
            });

            System.Threading.Tasks.Task.WaitAll(task1, task2);

            return(JsonContent(new
            {
                online = isOnline,
                uistate = uiState
            }));
        }
コード例 #3
0
        public ActionResult KeepAlive(string accesstoken)
        {
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            var redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_SESSION_KEY);

            redis.Exec(db => db.Execute("set", $"imuser_lastactivetime_{userid}", DateTime.Now.AsUnixTimestamp()));

            return(JsonContent <bool>(true));
        }
コード例 #4
0
        public ActionResult GetUserOnlineState(string accesstoken, string userid)
        {
            //var debuglog = new System.Text.StringBuilder();
            //debuglog.AppendLine($"datetime:{DateTime.Now.ToString()}");
            //debuglog.AppendLine($"accesstoken:{accesstoken}");
            //debuglog.AppendLine($"userid:{userid}");

            var isOnline       = false;
            var current_userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            //debuglog.AppendLine($"current_userid:{current_userid}");

            var imuser_usertoken = $"imuser_user_token_{userid}";
            var redis            = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_SESSION_KEY);
            var tokenList        = redis.Exec <RedisValue[]>(db => db.SetMembers(imuser_usertoken));

            if (tokenList != null && tokenList.Length > 0)
            {
                //debuglog.AppendLine($"tokenList:{String.Join(",", tokenList.Select(item => item.ToString()))}");

                //能在有效的token中找到client,只能说明在2小时内登陆过,还不能证明是当前在线的,但这是证明在线一个前提
                var clientFlags = new List <string>()
                {
                    ConstDefined.CLIENT_FLAG_WECHAT, ConstDefined.CLIENT_FLAG_MINIPROGRAM
                };
                var clientContain = false;

                foreach (var token in tokenList)
                {
                    var client = redis.Exec <string>(db => db.HashGet($"imuser_token_user_{token}", RedisFields.SESSION_TOKEN_CLIENTFLAG));
                    //debuglog.AppendLine($"{token}_client:{client}");
                    if (clientFlags.Contains(client))
                    {
                        //debuglog.AppendLine($"{token}_client_Contains:{client}");
                        clientContain = true;
                        break;
                    }
                }

                if (clientContain)
                {
                    //在判断最后一次活动时间,如果最后一次活动在5分钟以内就表示在新,否则表示不在线
                    var lasttime = redis.Exec <RedisResult>(db => db.Execute("get", $"imuser_lastactivetime_{userid}")).AsInt();
                    if (lasttime != 0 &&
                        (DateTime.Now - lasttime.AsDateTimeFromUnixTimestamp()).TotalSeconds <= Entity.ConstDefined.LASTACTIVETIME_MAX_SECONDS * 2)
                    {
                        isOnline = true;
                    }
                }
            }
            //System.IO.File.WriteAllText(Server.MapPath("~/1.txt"),debuglog.ToString());
            return(JsonContent(isOnline));
        }
コード例 #5
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetNotReadList(string accesstoken, string msgtypes)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            var notReadMsgList = new List <dynamic>();

            //从未读消息列表中取出未读消息的ID
            var notread_msg_uid_arr = FaceHand.Common.ResdisExecutor.ExecCommand <RedisValue[]>(
                db => db.SortedSetRangeByRank($"notreadlist_{userid}", 0, -1), RedisConfig.REDIS_MSGPOST_KEY);

            if (notread_msg_uid_arr != null && notread_msg_uid_arr.Length > 0)
            {
                var redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGCACHE_KEY);

                IEnumerable <int> msgtype_list = null;
                if (!String.IsNullOrEmpty(msgtypes))
                {
                    msgtype_list = msgtypes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(item => {
                        int t;
                        return(int.TryParse(item, out t) ? t : (int)item.AsEnum <MsgType>());
                    });
                }


                foreach (var msg_uid in notread_msg_uid_arr)
                {
                    redis.Exec(db => {
                        var msg = db.HashGetAll($"msg_{msg_uid}");
                        if (msg == null || msg.Length == 0)
                        {
                            return;
                        }

                        var msg_dict = msg.AsDictionary();
                        if (msgtype_list == null)
                        {
                            notReadMsgList.Add(msg_dict.BuildMsg());
                        }
                        else
                        {
                            if (msgtype_list.Contains(msg_dict.GetStringValue(RedisFields.MSG_TYPE).AsInt()))
                            {
                                notReadMsgList.Add(msg_dict.BuildMsg());
                            }
                        }
                    });
                }
            }

            return(JsonContent(notReadMsgList));
        }
コード例 #6
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult Send(string accesstoken, MsgType msgtype, string receivers, string msgbody, string extinfo)
        {
            //验证发送者
            var userid   = IMRedisDAL.GetUserIdByAccessToken(accesstoken);
            var userinfo = IMRedisDAL.GetUserInfo(userid);

            //接收人不能为空
            if (String.IsNullOrEmpty(receivers))
            {
                throw new BusinessException("消息接收人不能为空");
            }

            //验证消息体完整性
            ValidateMsgBody(msgtype, msgbody);

            //将消息放入消息缓存,放入消息缓存的目的是为了防止消息在发送失败时可以进行多次尝试
            var msg_uid = Guid.NewGuid().ToString();
            var redis   = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGCACHE_KEY);

            redis.Exec(db =>
            {
                var key = $"msg_{msg_uid}";
                db.HashSet(key, new HashEntry[] {
                    new HashEntry(RedisFields.MSG_UID, msg_uid),
                    new HashEntry(RedisFields.MSG_TYPE, (int)msgtype),
                    new HashEntry(RedisFields.MSG_SEND_USERTYPE, Convert.ToInt32(userinfo[RedisFields.USER_TYPE])),
                    new HashEntry(RedisFields.MSG_SEND_USERID, userid),
                    new HashEntry(RedisFields.MSG_RECEIVERS, receivers.NullDefault()),
                    new HashEntry(RedisFields.MSG_BODY, msgbody.NullDefault()),
                    new HashEntry(RedisFields.MSG_TRYCOUNT, 0),
                    new HashEntry(RedisFields.MSG_TRYTIME, 0),
                    new HashEntry(RedisFields.MSG_STATE, (byte)MsgSendState.Sending),
                    new HashEntry(RedisFields.MSG_SEND_TIME, DateTime.Now.AsUnixTimestamp()),
                    new HashEntry(RedisFields.USER_EXT_INFO, extinfo.NullDefault())
                });
            });

            //通知发送新消息
            redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGMQ_KEY);
            redis.Exec(db => {
                var batch = db.CreateBatch();
                //放入待发送队列
                batch.ListLeftPushAsync(MessageSendStateQueue.SENDING, msg_uid, When.Always, CommandFlags.FireAndForget);
                //通过订阅通知发送器异步处理发送
                batch.PublishAsync(RedisChannelName.NEW_MESSAGE_CHANNEL_TOPULLER, ConstDefined.PUBCMD_SEND, CommandFlags.FireAndForget);

                batch.Execute();
            });

            //返回消息ID
            return(JsonContent(new { msgid = msg_uid }));
        }
コード例 #7
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetMessage(string accesstoken, string msgid)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            //获取消息
            var redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGCACHE_KEY);
            var dict  = redis.Exec <Dictionary <string, string> >(db => db.HashGetAll($"msg_{msgid}").AsDictionary());

            if (dict == null || dict.Count == 0)
            {
                throw new BusinessException("消息未找到");
            }

            return(JsonContent(dict.BuildMsg()));
        }
コード例 #8
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetChatNotReadCount(string accesstoken, string chatuserids)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            if (String.IsNullOrEmpty(chatuserids))
            {
                throw new BusinessException("chatuserids不能为空");
            }

            var dict      = new Dictionary <string, int>();
            var user_list = chatuserids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (user_list.Length > 0)
            {
                var redis_msgpost = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGPOST_KEY);
                foreach (var r in user_list)
                {
                    //我发送的
                    //var k1 = $"chatnotreadcount_{userid}_{r}";
                    //我接收的
                    var k2    = $"chatnotreadcount_{r}_{userid}";
                    var count = redis_msgpost.Exec <int>(db => {
                        var count1 = 0;
                        var count2 = 0;

                        //var k1v = db.Execute("get", k1);
                        //if (k1v.HasValue() && !k1v.IsNull && !k1v.IsEmpty())
                        //    count1 = Convert.ToInt32(k1v.ToString());

                        var k2v = db.Execute("get", k2);
                        if (k2v.HasValue() && !k2v.IsNull && !k2v.IsEmpty())
                        {
                            count2 = Convert.ToInt32(k2v.ToString());
                        }

                        return(Math.Max(0, count1 + count2));
                    });

                    dict.Add(r, count);
                }
            }

            return(JsonContent(dict));
        }
コード例 #9
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetNotReadCount(string accesstoken, string msgtypes)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            var redis_msgpost = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGPOST_KEY);
            var count         = redis_msgpost.Exec <int>(db => {
                var lst = db.HashGetAll($"notreadcount_{userid}");
                if (lst == null || lst.Length == 0)
                {
                    return(0);
                }

                int re = 0;
                if (String.IsNullOrEmpty(msgtypes))
                {
                    foreach (HashEntry i in lst)
                    {
                        re += i.HasValue() ? Convert.ToInt32(i.Value) : 0;
                    }
                }
                else
                {
                    var msgtypes_lst = msgtypes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Select(item => {
                        int t;
                        return(int.TryParse(item, out t) ? t : (int)item.AsEnum <MsgType>());
                    });

                    foreach (HashEntry i in lst)
                    {
                        re += (i.HasValue() && msgtypes_lst.Contains(Convert.ToInt32(i.Name.ToString())))
                            ? Convert.ToInt32(i.Value) : 0;
                    }
                }

                return(re);
            });

            return(JsonContent <int>(Math.Max(count, 0)));
        }
コード例 #10
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetChatList(string accesstoken, string chatuserid, int pageIndex, int pageSize)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            if (String.IsNullOrEmpty(chatuserid))
            {
                throw new BusinessException("chatuserid不能为空");
            }

            pageIndex = Math.Max(1, pageIndex);
            pageSize  = Math.Max(5, pageSize);

            var dt = IMMySqlDAL.Instance.SelectChatMessageList(userid, chatuserid, pageIndex, pageSize);
            var re = new List <dynamic>();

            foreach (DataRow row in dt.Rows)
            {
                re.Add(row.BuildMsg());
            }

            return(JsonContent(re));
        }
コード例 #11
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult GetSendState(string accesstoken, string msgid)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            //获取消息
            var redis = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGCACHE_KEY);
            var dict  = redis.Exec <Dictionary <string, string> >(db => db.HashGetAll($"msg_{msgid}").AsDictionary());

            if (dict == null || dict.Count == 0)
            {
                throw new BusinessException("消息未找到");
            }

            return(JsonContent(new
            {
                state = dict.GetStringValue(RedisFields.MSG_STATE).AsInt(),
                errormsg = dict.GetStringValue(RedisFields.MSG_ERROR_MSG),
                trycount = dict.GetStringValue(RedisFields.MSG_TRYCOUNT).AsInt(),
                trytime = dict.GetStringValue(RedisFields.MSG_TRYTIME).AsLong(),
                receivers_success = dict.GetStringValue(RedisFields.MSG_SUCCESS_RECEIVERS),
                receivers_failed = dict.GetStringValue(RedisFields.MSG_FAILED_RECEIVERS)
            }));
        }
コード例 #12
0
        public ActionResult GetUserId(string accesstoken)
        {
            var current_userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            return(JsonContent <string>(current_userid));
        }
コード例 #13
0
ファイル: MessageController.cs プロジェクト: zztxcjm/im
        public ActionResult UpdateReadState(string accesstoken, string msg_uids)
        {
            //先验证访问权限
            var userid = IMRedisDAL.GetUserIdByAccessToken(accesstoken);

            if (!String.IsNullOrEmpty(msg_uids))
            {
                var msg_uid_list  = msg_uids.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var redis_msgpost = new FaceHand.Common.ResdisExecutor(RedisConfig.REDIS_MSGPOST_KEY);
                redis_msgpost.Exec(db => {
                    var chatMsgList = new List <Dictionary <string, string> >();

                    //更新整体的未读消息数量
                    var batch = db.CreateBatch();
                    foreach (string msg_uid in msg_uid_list)
                    {
                        var readtime = db.SortedSetScore($"readtime_{msg_uid}", userid);
                        if (!readtime.HasValue)
                        {
                            //从未读消息列表中移除
                            batch.SortedSetRemoveAsync($"notreadlist_{userid}", msg_uid, CommandFlags.FireAndForget);

                            //更新未读消息统计计数
                            var msg         = IMRedisDAL.GetMsg(msg_uid);
                            var msgtype_str = msg.GetStringValue(RedisFields.MSG_TYPE);
                            if (!String.IsNullOrEmpty(msgtype_str))
                            {
                                var count_rv = db.HashGet($"notreadcount_{userid}", msgtype_str);
                                if (count_rv.HasValue && !count_rv.IsNullOrEmpty)
                                {
                                    long count_lng = 0;
                                    if (count_rv.TryParse(out count_lng))
                                    {
                                        if (count_lng > 0)
                                        {
                                            batch.HashDecrementAsync($"notreadcount_{userid}", msgtype_str, 1, CommandFlags.FireAndForget);
                                        }
                                        else
                                        {
                                            batch.HashSetAsync($"notreadcount_{userid}", msgtype_str, 0);
                                        }
                                    }
                                }

                                //如果是聊天消息,更新聊天消息的阅读情况
                                var msgtype_int = Convert.ToInt32(msgtype_str);
                                if (msgtype_int < 60)
                                {
                                    chatMsgList.Add(msg);
                                }
                            }

                            //更新阅读时间
                            batch.SortedSetAddAsync($"readtime_{msg_uid}",
                                                    new SortedSetEntry[] { new SortedSetEntry(userid, DateTime.Now.AsUnixTimestamp()) }, CommandFlags.FireAndForget);
                        }
                    }

                    batch.Execute();

                    //更新聊天消息和接收者之间的的未读数量
                    if (chatMsgList.Count > 0)
                    {
                        var batch2 = db.CreateBatch();
                        foreach (var msg in chatMsgList)
                        {
                            var msg_senderid = msg.GetStringValue(RedisFields.MSG_SEND_USERID);
                            var receivers    = msg.GetStringValue(RedisFields.MSG_SUCCESS_RECEIVERS);
                            if (!String.IsNullOrEmpty(receivers))
                            {
                                var receivers_list = receivers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var receiver_userid in receivers_list)
                                {
                                    var k        = $"chatnotreadcount_{msg_senderid}_{receiver_userid}";
                                    var count_rv = db.Execute("get", k);
                                    if (count_rv.HasValue() && !count_rv.IsNull && !count_rv.IsEmpty())
                                    {
                                        //这个key必须大于0才执行递减操作
                                        //否则不变
                                        if (count_rv.AsInt() > 0)
                                        {
                                            batch2.ExecuteAsync("DECRBY", k, 1);
                                        }
                                        else
                                        {
                                            batch2.ExecuteAsync("set", k, 0);
                                        }
                                    }
                                    else
                                    {
                                        //这个key还不存在
                                        batch2.ExecuteAsync("set", k, 0);
                                    }
                                }
                            }
                        }
                        batch2.Execute();
                    }
                });
            }

            return(JsonContent(true));
        }