示例#1
0
        /// <summary>
        /// 線程執行體,登錄驗證
        /// </summary>
        /// <param name="obj"></param>
        private void ThreadLoginCheckFunc(object objs)
        {
            if (objs != null)
            {
                //2016/02/27
                object obj = ((List<object>)objs)[0];  // 用戶Socket
                object tobj = ((List<object>)objs)[1]; // 登錄線程
                Thread LoginThread = (Thread)tobj;

                try
                {
                    string UserID = "";
                    Socket newClient = obj as Socket;
                    //返回解包后的資料(返回數組 0=type ; 1=終端; 2=群號; 3=時間; 4=消息ID; 5=消息內容; 6=終端姓名)
                    // type = "0" 是PC登錄; type = "WS" 是Web登錄
                    object[] ReceiveData = ConvertMethod.ParseLoginData(newClient, LoginTimeOut); //ConvertMethod.UnMsgPackage(newClient);

                    string DataType = ReceiveData[0].ToString();
                    string DataTerminal = ReceiveData[1].ToString();
                    //普通用戶登錄為空
                    //APP登錄為APP
                    //訂閱號登錄為SUB(會有一個特別的HashTable來保存訂閱號的連接)
                    string DataGroup = ReceiveData[2].ToString();
                    string DataTerminalName = ReceiveData[6].ToString();
                    string DataText = ReceiveData[5].ToString();
                    if (DataType == "0" && DataTerminal.Length > 0)
                    {
                        //test
                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "PC端" + DataTerminal + "請求登錄");
                        //LogHelper.WriteLog("StartUp()", "PC端用戶: " + DataTerminal + "-" + DataTerminalName + " 請求登錄");
                        UserID = DataTerminal; // 用戶帳號
                        bool Passed = true;
                        switch (DataGroup.ToUpper())
                        {
                            case "SUB":

                                #region " 訂閱號登錄 "
                                //未開工2016/01/26
                                #endregion

                                break;

                            case "APP":

                                #region " APP登錄 "

                                try
                                {
                                    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, DataGroup, Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                    lock (newClient)
                                    {
                                        foreach (byte[] msg in msgs)
                                        {
                                            newClient.Send(msg);
                                            //SendData(newClient, msg);
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Passed = false;
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():服務器開放登錄功能", "發送登陸成功信息時:" + ex.Message);
                                    LogHelper.WriteLog("StartUp()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                                }

                                if (Passed)
                                {
                                    //創建連接對象
                                    UserSocket AppUser = new UserSocket();
                                    AppUser.ID = UserID;
                                    AppUser.Socket = newClient;
                                    AppUser.State = UserSocket.UserStates.Online;

                                    // 將新連接加入轉發表並創建線程為其服務
                                    // Key-GUID永不重複
                                    _app_transmit_tb.Add(UserID, AppUser);

                                    try
                                    {
                                        Thread clientThread = new Thread(new ParameterizedThreadStart(AppThreadFunc));
                                        //加入哈希表
                                        _app_thread_tb.Add(UserID, clientThread);
                                        clientThread.Start(UserID);
                                    }
                                    catch (Exception ex)
                                    {
                                        try
                                        {
                                            //清除已加入的連接 
                                            _app_transmit_tb.Remove(UserID);
                                        }
                                        catch
                                        { }
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():開啟新線程", "建立登入用戶新線程時:" + ex.Message);
                                        LogHelper.WriteLog("StartUp()", "建立登入用戶" + DataTerminal + "-" + DataTerminalName + "新線程時:" + (ex != null ? ex.Message : ""));
                                    }
                                }

                                #endregion

                                break;
                            case "MOBILE":

                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "發現非常進入者:" + DataTerminal);

                                #region " 移動端登錄 "

                                UserSocket MobileUser = _mobile_transmit_tb[DataTerminal] as UserSocket;
                                if (MobileUser != null)
                                {
                                    Socket curSkt = MobileUser.Socket;

                                    #region " 發送離線 "

                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("00", "7", DataTerminal, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //如果2秒內得不到之前登陸的對象,就直接干掉
                                        //否則此帳號將永遠無法登錄
                                        if (Monitor.TryEnter(curSkt, 2000))
                                        {
                                            try
                                            {
                                                //向用戶本人發送離線
                                                foreach (byte[] msg in msgs)
                                                {
                                                    curSkt.Send(msg);
                                                    //SendData(curSkt, msg);
                                                }
                                            }
                                            catch
                                            { }
                                            finally
                                            {
                                                Monitor.Exit(curSkt);
                                            }
                                        }
                                        else
                                        {
                                            //如果到這里說明之前登陸的對象已經死鎖                                            
                                        }

                                        UpdateUserLog(UserID, "1", "0", "因相同帳號再次登陸而強制離線.");

                                        //log
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "相同帳號再次登陸:" + DataTerminal + " " + DataTerminalName);
                                        //LogHelper.WriteLog("StartUp()", "相同帳號再次登陸:" + DataTerminal + " " + DataTerminalName);
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "轉發用戶" + UserID + "離線消息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "轉發用戶" + UserID + "離線消息時:" + (ex != null ? ex.Message : ""));
                                    }
                                    try
                                    {
                                        if (curSkt.Connected)
                                        {
                                            curSkt.Shutdown(SocketShutdown.Both);
                                            //curSkt.Disconnect(false);
                                        }
                                        curSkt.Close();
                                        curSkt = null;

                                        Thread thread = _mobile_thread_tb[DataTerminal] as Thread;
                                        if (thread != null)
                                        {
                                            thread.Abort();
                                            //線程池不會被遍歷,不鎖.
                                            _mobile_thread_tb.Remove(DataTerminal);
                                        }
                                        lock (_transmit_tb.SyncRoot)
                                            _mobile_transmit_tb.Remove(DataTerminal);
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "嘗試關閉用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "嘗試關閉用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                    }

                                    #endregion
                                }
                                // 驗證是否為唯一用戶
                                if (_mobile_transmit_tb.Count != 0 && _mobile_transmit_tb.ContainsKey(UserID))
                                {
                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄失敗.", "3", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in msgs)
                                            {
                                                newClient.Send(msg);
                                                //SendData(newClient, msg);
                                            }
                                        }
                                        //test
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "PC端" + DataTerminal + "登錄失敗");
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "移動客戶端" + DataTerminal + "登錄失敗");
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():驗證是否為唯一用戶", "發送登陸失敗信息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "發送登陸失敗信息時" + (ex != null ? ex.Message : ""));
                                    }
                                }
                                else
                                {
                                    // 服務器開放登錄功能
                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, DataGroup, Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in msgs)
                                            {
                                                newClient.Send(msg);
                                                //SendData(newClient, msg);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Passed = false;
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():服務器開放登錄功能", "發送登陸成功信息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                                    }

                                    if (Passed)
                                    {
                                        //創建連接對象
                                        MobileUser = new UserSocket();
                                        MobileUser.ID = UserID;
                                        MobileUser.Socket = newClient;
                                        MobileUser.State = UserSocket.UserStates.Online;

                                        //登錄時群號規則: 普通用戶登錄時為空格, 手機應用登錄時為"MOBILE"
                                        using (SQLHelper conn = new SQLHelper(DBInfo))
                                        {
                                            conn.OpenConnection();
                                            try
                                            {
                                                #region " 獲得當前用記的所有聯絡人并向他們推送用戶上線消息 "

                                                StateNotifyQueue.Enqueue(new List<object>() { MobileUser, "1" });

                                                #endregion

                                                //Test
                                                //LogHelper.WriteLog("ThreadLoginCheckFunc()", User.ID + "推送未讀消息.");

                                                #region " 發送所有未讀訊息和群命令 "

                                                #region " 訊息 "

                                                DataTable MsgsList = GetUnreadMsgs(conn, UserID, "M");
                                                if (MsgsList.Rows.Count > 0)
                                                {
                                                    if (newClient != null)
                                                    {
                                                        if (MsgsList.Rows.Count > 0)
                                                        {
                                                            long MaxMsgNO = 0;
                                                            foreach (DataRow UnreadMsg in MsgsList.Rows)
                                                            {
                                                                // 記錄最大MsgNO
                                                                if (MaxMsgNO < long.Parse(UnreadMsg["msg_no"].ToString()))
                                                                    MaxMsgNO = long.Parse(UnreadMsg["msg_no"].ToString());

                                                                // 發給登錄人
                                                                DateTime MsgDT = DateTime.Parse(UnreadMsg["msg_date"].ToString() + " " + UnreadMsg["msg_time"].ToString());
                                                                // 判斷個人消息還是群消息
                                                                List<byte[]> rtnMsgs = ConvertMethod.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                    UnreadMsg["td_no"].ToString().Length > 0 ? "4" : (UnreadMsg["msg_doctype"].ToString() == "0" ? "P" : "U"),
                                                                                                                      UnreadMsg["msg_from"].ToString(),
                                                                                                                      UnreadMsg["user_name"].ToString(),
                                                                                                                      UnreadMsg["td_no"].ToString(),
                                                                                                                      MsgDT,
                                                                                                                      UnreadMsg["msg_guid"].ToString(),
                                                                                                                      UnreadMsg["msg_no"].ToString(),
                                                                                                                      "");
                                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                                lock (newClient)
                                                                {
                                                                    foreach (byte[] msg in rtnMsgs)
                                                                    {
                                                                        newClient.Send(msg);
                                                                        //SendData(newClient, msg);
                                                                    }
                                                                }
                                                            }

                                                            // 更新為已讀 
                                                            try
                                                            {
                                                                MarkReadHistoryMsgQueue.Enqueue("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                                //conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                            }
                                                            catch (Exception ex)
                                                            {
                                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "標識歷史信息為已讀時:" + (ex != null ? ex.Message : ""));
                                                            }
                                                        }
                                                    }
                                                    //Test
                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "共向移動端用戶:" + MobileUser.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史未讀消息.");
                                                }

                                                #endregion

                                                #region " 系統消息 "

                                                MsgsList = GetUnreadMsgs(conn, UserID, "S");
                                                if (MsgsList.Rows.Count > 0)
                                                {
                                                    if (newClient != null)
                                                    {
                                                        if (MsgsList.Rows.Count > 0)
                                                        {
                                                            long MaxMsgNO = 0;
                                                            foreach (DataRow UnreadMsg in MsgsList.Rows)
                                                            {
                                                                // 記錄最大MsgNO
                                                                if (MaxMsgNO < long.Parse(UnreadMsg["sys_id"].ToString()))
                                                                    MaxMsgNO = long.Parse(UnreadMsg["sys_id"].ToString());

                                                                // 發給登錄人
                                                                DateTime MsgDT = DateTime.Parse(UnreadMsg["sys_date"].ToString() + " " + UnreadMsg["sys_time"].ToString());
                                                                // 判斷個人消息還是群消息
                                                                List<byte[]> rtnMsgs = ConvertMethod.ConvertMsgToByte(UnreadMsg["sys_remk"].ToString(),
                                                                                                                      UnreadMsg["sys_type"].ToString() == "1" ? "D" : "*",
                                                                                                                      UnreadMsg["sys_type"].ToString(),
                                                                                                                      UnreadMsg["sys_objtype"].ToString(),
                                                                                                                      "*",
                                                                                                                      MsgDT,
                                                                                                                      UnreadMsg["sys_objid"].ToString(),
                                                                                                                      UnreadMsg["sys_id"].ToString(),
                                                                                                                      "");
                                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                                lock (newClient)
                                                                {
                                                                    foreach (byte[] msg in rtnMsgs)
                                                                    {
                                                                        newClient.Send(msg);
                                                                        //SendData(newClient, msg);
                                                                    }
                                                                }
                                                            }

                                                            // 更新為已讀 
                                                            try
                                                            {
                                                                MarkReadHistoryMsgQueue.Enqueue("update a set a.sysmsg_state='1' from lrsysmsgstate a where a.sys_id<=" + MaxMsgNO.ToString() + " and a.sysmsg_to='" + UserID + "' and a.sysmsg_state='0'");
                                                                //conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                            }
                                                            catch (Exception ex)
                                                            {
                                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "標識歷史系統消息為已讀時:" + (ex != null ? ex.Message : ""));
                                                            }
                                                        }
                                                    }
                                                    //Test
                                                    //LogHelper.WriteLog("ThreadLoginCheckFunc()", "共向用戶:" + User.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史命令.");
                                                }

                                                #endregion

                                                MsgsList.Dispose();
                                                MsgsList = null;

                                                #endregion

                                            }
                                            catch (SocketException ex)
                                            {
                                                //test
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "向PC端" + DataTerminal + "推送未讀信息和命令時出錯." + (ex != null ? ex.Message : ""));
                                            }

                                            //更新用戶狀態
                                            try
                                            {
                                                DoUpdateUserLog(conn, UserID, "0", "0", "登錄");
                                                DoUpdateUserState(conn, UserID, "1"); //上線中
                                            }
                                            catch (Exception ex)
                                            {
                                                Passed = false;
                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "更新PC端用戶:" + DataTerminal + "狀態." + (ex != null ? ex.Message : ""));
                                            }

                                            conn.CloseConnection();
                                        }
                                        if (Passed)
                                        {
                                            #region " 向移動端 客戶端推送平臺數據(在線人數等) - 暫不推送 "
                                            //try
                                            //{
                                            //    List<byte[]> MsgToPC = ConvertMethod.ConvertMsgToByte(string.Format(SysMessage, ActiveUsersCount,
                                            //                                                                                    OnlineUsersCount,
                                            //                                                                                    RegisteredUsersCount,
                                            //                                                                                    TodayMessagesCount,
                                            //                                                                                    TotalMessagesCount),
                                            //                                                          "9", "", "", "", "", "");
                                            //    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                            //    lock (newClient)
                                            //    {
                                            //        foreach (byte[] msg in MsgToPC)
                                            //        {
                                            //            newClient.Send(msg);
                                            //            //SendData(newClient, msg);
                                            //        }
                                            //    }
                                            //}
                                            //catch (SocketException ex)
                                            //{
                                            //    Passed = false;
                                            //    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                            //    LogHelper.WriteLog("ThreadLoginCheckFunc()", "向PC端" + DataTerminal + "推送平臺數據(在線人數等)." + (ex != null ? ex.Message : ""));
                                            //}
                                            #endregion
                                        }

                                        if (Passed)
                                        {
                                            // 將新連接加入轉發表並創建線程為其服務
                                            lock (_mobile_transmit_tb.SyncRoot)
                                            {
                                                _mobile_transmit_tb.Add(UserID, MobileUser);
                                            }

                                            try
                                            {
                                                Thread clientThread = new Thread(new ParameterizedThreadStart(MobileThreadFunc));
                                                //加入哈希表
                                                _mobile_thread_tb.Add(UserID, clientThread);
                                                //clientThread.Start(userName);
                                                clientThread.Start(UserID);
                                            }
                                            catch (Exception ex)
                                            {
                                                try
                                                {
                                                    // 發生錯誤時移除連接
                                                    lock (_mobile_transmit_tb.SyncRoot)
                                                    {
                                                        //_transmit_tb.Add(UserID, newClient);
                                                        _mobile_transmit_tb.Remove(UserID);
                                                    }
                                                }
                                                catch
                                                { }
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():開啟新線程", "建立登入用戶新線程時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "建立登入用戶" + DataTerminal + "-" + DataTerminalName + "新線程時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                    }
                                }

                                #endregion

                                break;
                            case "FILE":

                                #region " 文件傳送帳號登錄 "
                                Passed = true;
                                //try
                                //{
                                //    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, DataGroup, Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                //    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                //    lock (newClient)
                                //    {
                                //        foreach (byte[] msg in msgs)
                                //        {
                                //            newClient.Send(msg);
                                //        }
                                //    }
                                //}
                                //catch (Exception ex)
                                //{
                                //    Passed = false;
                                //    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():服務器開放登錄功能", "發送登陸成功信息時:" + ex.Message);
                                //    LogHelper.WriteLog("StartUp()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                                //}

                                if (Passed)
                                {
                                    //創建連接對象
                                    UserSocket AppUser = new UserSocket();
                                    AppUser.ID = UserID;
                                    AppUser.Socket = newClient;
                                    AppUser.State = UserSocket.UserStates.Online;
                                    AppUser.Type = "F";
                                    AppUser.SenderID = DataText.Split(new char[] { '|' })[0].Trim();
                                    AppUser.ReceiverID = DataText.Split(new char[] { '|' })[1].Trim();
                                    // 將新連接加入轉發表並創建線程為其服務
                                    // Key-GUID永不重複
                                    _file_transmit_tb.Add(UserID, AppUser);

                                    try
                                    {
                                        // 2016/02/22
                                        // 接收者只能接收數據,不需要開啟Server-Reveived線程
                                        if (UserID.Substring(UserID.Length - 1, 1) != "R")
                                        {
                                            Thread clientThread = new Thread(new ParameterizedThreadStart(FileThreadFunc));
                                            //加入哈希表
                                            _file_thread_tb.Add(UserID, clientThread);
                                            clientThread.Start(UserID);
                                        }
                                        else
                                        {
                                            //接收者已經登錄.找到S通道的發送者并向他發送允許建立T通道的通知.
                                            //發送者ID-接收者ID-GUID-R/S中第一個為對方的S通道帳號
                                            //string SenderID = UserID.Substring(0, 50).Trim();
                                            //string SenderGUID = UserID.Substring(51, 32).Trim();
                                            string SenderGUID = UserID.Substring(0, UserID.Length - 2).Trim();
                                            //缺異常處理.報錯后必須將接收者的T通道關閉
                                            string MsgNO = ProcessTransferFileRequest("P", AppUser.SenderID, "P", AppUser.SenderID, "R", SenderGUID, "FILE", "RECEIVER");
                                            if (MsgNO.Length == 0)
                                            {
                                                try
                                                {
                                                    if (AppUser.Socket.Connected)
                                                    {
                                                        AppUser.Socket.Shutdown(SocketShutdown.Both);
                                                    }
                                                    AppUser.Socket.Close();
                                                    //LogHelper.WriteLog("StartUp()", "無效登錄請求被丟棄");
                                                }
                                                catch
                                                {
                                                }
                                                try
                                                {
                                                    //清除已加入的連接 
                                                    _file_transmit_tb.Remove(UserID);
                                                }
                                                catch
                                                { }
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        try
                                        {
                                            //清除已加入的連接 
                                            _file_transmit_tb.Remove(UserID);
                                        }
                                        catch
                                        { }
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():開啟新線程", "建立登入用戶新線程時:" + ex.Message);
                                        LogHelper.WriteLog("StartUp()", "建立登入用戶" + DataTerminal + "-" + DataTerminalName + "新線程時:" + (ex != null ? ex.Message : ""));
                                    }
                                }

                                #endregion

                                break;
                            default:

                                #region " PC端登錄 "

                                UserSocket User = _transmit_tb[DataTerminal] as UserSocket;
                                if (User != null)
                                {
                                    Socket curSkt = User.Socket;

                                    #region " 發送離線 "

                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("00", "7", DataTerminal, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //如果2秒內得不到之前登陸的對象,就直接干掉
                                        //否則此帳號將永遠無法登錄
                                        if (Monitor.TryEnter(curSkt, 2000))
                                        {
                                            try
                                            {
                                                //向用戶本人發送離線
                                                foreach (byte[] msg in msgs)
                                                {
                                                    curSkt.Send(msg);
                                                    //SendData(curSkt, msg);
                                                }
                                            }
                                            catch
                                            { }
                                            finally
                                            {
                                                Monitor.Exit(curSkt);
                                            }
                                        }
                                        else
                                        {
                                            //如果到這里說明之前登陸的對象已經死鎖                                            
                                        }
                                        //lock (curSkt)
                                        //{
                                        //    //向用戶本人發送離線
                                        //    foreach (byte[] msg in msgs)
                                        //    {
                                        //        curSkt.Send(msg);
                                        //    }
                                        //}

                                        UpdateUserLog(UserID, "1", "0", "因相同帳號再次登陸而強制離線.");

                                        //log
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "相同帳號再次登陸:" + DataTerminal + " " + DataTerminalName);
                                        //LogHelper.WriteLog("StartUp()", "相同帳號再次登陸:" + DataTerminal + " " + DataTerminalName);
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "轉發用戶" + UserID + "離線消息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "轉發用戶" + UserID + "離線消息時:" + (ex != null ? ex.Message : ""));
                                    }
                                    try
                                    {
                                        if (curSkt.Connected)
                                        {
                                            curSkt.Shutdown(SocketShutdown.Both);
                                            //curSkt.Disconnect(false);
                                        }
                                        curSkt.Close();
                                        curSkt = null;

                                        Thread thread = _thread_tb[DataTerminal] as Thread;
                                        if (thread != null)
                                        {
                                            thread.Abort();
                                            //線程池不會被遍歷,不鎖.
                                            _thread_tb.Remove(DataTerminal);
                                        }
                                        lock (_transmit_tb.SyncRoot)
                                            _transmit_tb.Remove(DataTerminal);
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "嘗試關閉用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "嘗試關閉用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                    }

                                    #endregion
                                }
                                // 驗證是否為唯一用戶
                                if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserID))
                                {
                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄失敗.", "3", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in msgs)
                                            {
                                                newClient.Send(msg);
                                                //SendData(newClient, msg);
                                            }
                                        }
                                        //test
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "PC端" + DataTerminal + "登錄失敗");
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "PC端" + DataTerminal + "登錄失敗");
                                    }
                                    catch (SocketException ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():驗證是否為唯一用戶", "發送登陸失敗信息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "發送登陸失敗信息時" + (ex != null ? ex.Message : ""));
                                    }
                                }
                                else
                                {
                                    // 服務器開放登錄功能
                                    try
                                    {
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, DataGroup, Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in msgs)
                                            {
                                                newClient.Send(msg);
                                                //SendData(newClient, msg);
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Passed = false;
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():服務器開放登錄功能", "發送登陸成功信息時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                                    }

                                    if (Passed)
                                    {
                                        //創建連接對象
                                        User = new UserSocket();
                                        User.ID = UserID;
                                        User.Socket = newClient;
                                        User.State = UserSocket.UserStates.Online;

                                        //登錄時群號規則: 普通用戶登錄時為空格, 外接應用(APP)登錄時為"APP"
                                        #region " 普通用戶才做以下操作 "
                                        if (DataGroup.Length == 0)
                                        {
                                            using (SQLHelper conn = new SQLHelper(DBInfo))
                                            {
                                                conn.OpenConnection();
                                                try
                                                {
                                                    #region " 獲得當前用記的所有聯絡人并向他們推送用戶上線消息 "

                                                    StateNotifyQueue.Enqueue(new List<object>() { User, "1" });

                                                    //DataTable ContactsList = GetContacts(conn, UserID);
                                                    //if (ContactsList.Rows.Count > 0)
                                                    //{
                                                    //    foreach (DataRow Contact in ContactsList.Rows)
                                                    //    {
                                                    //        //加入聯絡人(防呆自己加自己)
                                                    //        if (User.ID != Contact["contact_id"].ToString())
                                                    //            User.Contacts.Add(Contact["contact_id"].ToString());
                                                    //    }
                                                    //    //2016/02/27
                                                    //    //For Test
                                                    //    //改為獨立線程來發,讓用戶登錄不受影響
                                                    //    //如果此聯絡人在線就通知他(她)當前用戶上線了
                                                    //    try
                                                    //    {
                                                    //        Thread stateThread = new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc));
                                                    //        stateThread.Start(User);
                                                    //    }
                                                    //    catch
                                                    //    { }
                                                    //    //SendUserState(User);
                                                    //}
                                                    //ContactsList.Dispose();
                                                    //ContactsList = null;

                                                    #endregion

                                                    //Test
                                                    //LogHelper.WriteLog("ThreadLoginCheckFunc()", User.ID + "推送未讀消息.");

                                                    #region " 發送所有未讀訊息和群命令 "

                                                    #region " 訊息 "

                                                    DataTable MsgsList = GetUnreadMsgs(conn, UserID, "M");
                                                    if (MsgsList.Rows.Count > 0)
                                                    {
                                                        if (newClient != null)
                                                        {
                                                            if (MsgsList.Rows.Count > 0)
                                                            {
                                                                long MaxMsgNO = 0;
                                                                foreach (DataRow UnreadMsg in MsgsList.Rows)
                                                                {
                                                                    // 記錄最大MsgNO
                                                                    if (MaxMsgNO < long.Parse(UnreadMsg["msg_no"].ToString()))
                                                                        MaxMsgNO = long.Parse(UnreadMsg["msg_no"].ToString());

                                                                    // 發給登錄人
                                                                    DateTime MsgDT = DateTime.Parse(UnreadMsg["msg_date"].ToString() + " " + UnreadMsg["msg_time"].ToString());
                                                                    // 判斷個人消息還是群消息
                                                                    List<byte[]> rtnMsgs = ConvertMethod.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                        UnreadMsg["td_no"].ToString().Length > 0 ? "4" : (UnreadMsg["msg_doctype"].ToString() == "0" ? "P" : "U"),
                                                                                                                          UnreadMsg["msg_from"].ToString(),
                                                                                                                          UnreadMsg["user_name"].ToString(),
                                                                                                                          UnreadMsg["td_no"].ToString(),
                                                                                                                          MsgDT,
                                                                                                                          UnreadMsg["msg_guid"].ToString(),
                                                                                                                          UnreadMsg["msg_no"].ToString(),
                                                                                                                          "");
                                                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                                    lock (newClient)
                                                                    {
                                                                        foreach (byte[] msg in rtnMsgs)
                                                                        {
                                                                            newClient.Send(msg);
                                                                            //SendData(newClient, msg);
                                                                        }
                                                                    }
                                                                }

                                                                // 更新為已讀 
                                                                try
                                                                {
                                                                    MarkReadHistoryMsgQueue.Enqueue("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                                    //conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                                }
                                                                catch (Exception ex)
                                                                {
                                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "標識歷史信息為已讀時:" + (ex != null ? ex.Message : ""));
                                                                }
                                                            }
                                                        }
                                                        //Test
                                                        LogHelper.WriteLog("ThreadLoginCheckFunc()", "共向用戶:" + User.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史未讀消息.");
                                                    }

                                                    #endregion

                                                    #region " 命令(取消推送) "

                                                    //MsgsList = GetUnreadMsgs(conn, UserID, "C");
                                                    //if (MsgsList.Rows.Count > 0)
                                                    //{
                                                    //    if (newClient != null)
                                                    //    {
                                                    //        if (MsgsList.Rows.Count > 0)
                                                    //        {
                                                    //            long MaxMsgNO = 0;
                                                    //            foreach (DataRow UnreadMsg in MsgsList.Rows)
                                                    //            {
                                                    //                // 記錄最大MsgNO
                                                    //                if (MaxMsgNO < long.Parse(UnreadMsg["cmd_no"].ToString()))
                                                    //                    MaxMsgNO = long.Parse(UnreadMsg["cmd_no"].ToString());

                                                    //                // 發給登錄人
                                                    //                DateTime MsgDT = DateTime.Parse(UnreadMsg["cmd_date"].ToString() + " " + UnreadMsg["cmd_time"].ToString());
                                                    //                // 判斷個人消息還是群消息
                                                    //                List<byte[]> rtnMsgs = ConvertMethod.ConvertMsgToByte(UnreadMsg["cmd_text"].ToString(),
                                                    //                                                                      "C",
                                                    //                                                                      UnreadMsg["cmd_user"].ToString(),
                                                    //                                                                      UnreadMsg["user_name"].ToString(),
                                                    //                                                                      UnreadMsg["td_no"].ToString(),
                                                    //                                                                      MsgDT,
                                                    //                                                                      UnreadMsg["cmd_guid"].ToString(),
                                                    //                                                                      UnreadMsg["cmd_no"].ToString());
                                                    //                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                    //                lock (newClient)
                                                    //                {
                                                    //                    foreach (byte[] msg in rtnMsgs)
                                                    //                    {
                                                    //                        newClient.Send(msg);
                                                    //                        //SendData(newClient, msg);
                                                    //                    }
                                                    //                }
                                                    //            }

                                                    //            // 更新為已讀 
                                                    //            try
                                                    //            {
                                                    //                MarkReadHistoryMsgQueue.Enqueue("update a set a.cmd_state='1' from lrcmdstate a where a.cmd_no<=" + MaxMsgNO.ToString() + " and a.cmd_to='" + UserID + "' and a.cmd_state='0'");
                                                    //                //conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                    //            }
                                                    //            catch (Exception ex)
                                                    //            {
                                                    //                LogHelper.WriteLog("ThreadLoginCheckFunc()", "標識歷史命令為已讀時:" + (ex != null ? ex.Message : ""));
                                                    //            }
                                                    //        }
                                                    //    }
                                                    //    //Test
                                                    //    LogHelper.WriteLog("ThreadLoginCheckFunc()", "共向用戶:" + User.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史命令.");
                                                    //}

                                                    #endregion

                                                    #region " 系統消息 "

                                                    MsgsList = GetUnreadMsgs(conn, UserID, "S");
                                                    if (MsgsList.Rows.Count > 0)
                                                    {
                                                        if (newClient != null)
                                                        {
                                                            if (MsgsList.Rows.Count > 0)
                                                            {
                                                                long MaxMsgNO = 0;
                                                                foreach (DataRow UnreadMsg in MsgsList.Rows)
                                                                {
                                                                    // 記錄最大MsgNO
                                                                    if (MaxMsgNO < long.Parse(UnreadMsg["sys_id"].ToString()))
                                                                        MaxMsgNO = long.Parse(UnreadMsg["sys_id"].ToString());

                                                                    // 發給登錄人
                                                                    DateTime MsgDT = DateTime.Parse(UnreadMsg["sys_date"].ToString() + " " + UnreadMsg["sys_time"].ToString());
                                                                    // 判斷個人消息還是群消息
                                                                    List<byte[]> rtnMsgs = ConvertMethod.ConvertMsgToByte(UnreadMsg["sys_remk"].ToString(),
                                                                                                                          UnreadMsg["sys_type"].ToString() == "1" ? "D" : "*",
                                                                                                                          UnreadMsg["sys_type"].ToString(),
                                                                                                                          UnreadMsg["sys_objtype"].ToString(),
                                                                                                                          "*",
                                                                                                                          MsgDT,
                                                                                                                          UnreadMsg["sys_objid"].ToString(),
                                                                                                                          UnreadMsg["sys_id"].ToString(),
                                                                                                                          "");
                                                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                                    lock (newClient)
                                                                    {
                                                                        foreach (byte[] msg in rtnMsgs)
                                                                        {
                                                                            newClient.Send(msg);
                                                                            //SendData(newClient, msg);
                                                                        }
                                                                    }
                                                                }

                                                                // 更新為已讀 
                                                                try
                                                                {
                                                                    MarkReadHistoryMsgQueue.Enqueue("update a set a.sysmsg_state='1' from lrsysmsgstate a where a.sys_id<=" + MaxMsgNO.ToString() + " and a.sysmsg_to='" + UserID + "' and a.sysmsg_state='0'");
                                                                    //conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_no<=" + MaxMsgNO.ToString() + " and a.msg_to='" + UserID + "' and a.msg_state='0'");
                                                                }
                                                                catch (Exception ex)
                                                                {
                                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "標識歷史系統消息為已讀時:" + (ex != null ? ex.Message : ""));
                                                                }
                                                            }
                                                        }
                                                        //Test
                                                        //LogHelper.WriteLog("ThreadLoginCheckFunc()", "共向用戶:" + User.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史命令.");
                                                    }

                                                    #endregion

                                                    MsgsList.Dispose();
                                                    MsgsList = null;

                                                    #endregion

                                                }
                                                catch (SocketException ex)
                                                {
                                                    //test
                                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "向PC端" + DataTerminal + "推送未讀信息和命令時出錯." + (ex != null ? ex.Message : ""));
                                                }

                                                //更新用戶狀態
                                                try
                                                {
                                                    DoUpdateUserLog(conn, UserID, "0", "0", "登錄");
                                                    DoUpdateUserState(conn, UserID, "1"); //上線中
                                                }
                                                catch (Exception ex)
                                                {
                                                    Passed = false;
                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "更新PC端用戶:" + DataTerminal + "狀態." + (ex != null ? ex.Message : ""));
                                                }

                                                conn.CloseConnection();
                                            }
                                            if (Passed)
                                            {
                                                #region " 向PC客戶端推送平臺數據(在線人數等) "
                                                try
                                                {
                                                    List<byte[]> MsgToPC = ConvertMethod.ConvertMsgToByte(string.Format(SysMessage, ActiveUsersCount,
                                                                                                                                    OnlineUsersCount,
                                                                                                                                    RegisteredUsersCount,
                                                                                                                                    TodayMessagesCount,
                                                                                                                                    TotalMessagesCount),
                                                                                                          "9", "", "", "", "", "");
                                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                    lock (newClient)
                                                    {
                                                        foreach (byte[] msg in MsgToPC)
                                                        {
                                                            newClient.Send(msg);
                                                            //SendData(newClient, msg);
                                                        }
                                                    }
                                                }
                                                catch (SocketException ex)
                                                {
                                                    Passed = false;
                                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                                    LogHelper.WriteLog("ThreadLoginCheckFunc()", "向PC端" + DataTerminal + "推送平臺數據(在線人數等)." + (ex != null ? ex.Message : ""));
                                                }
                                                #endregion
                                            }
                                        }
                                        #endregion

                                        if (Passed)
                                        {
                                            // 將新連接加入轉發表並創建線程為其服務
                                            lock (_transmit_tb.SyncRoot)
                                            {
                                                //_transmit_tb.Add(UserID, newClient);
                                                _transmit_tb.Add(UserID, User);
                                            }

                                            try
                                            {
                                                Thread clientThread = new Thread(new ParameterizedThreadStart(ThreadFunc));
                                                //加入哈希表
                                                _thread_tb.Add(UserID, clientThread);
                                                //clientThread.Start(userName);
                                                clientThread.Start(UserID);
                                            }
                                            catch (Exception ex)
                                            {
                                                try
                                                {
                                                    // 發生錯誤時移除連接
                                                    lock (_transmit_tb.SyncRoot)
                                                    {
                                                        //_transmit_tb.Add(UserID, newClient);
                                                        _transmit_tb.Remove(UserID);
                                                    }
                                                }
                                                catch
                                                { }
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():開啟新線程", "建立登入用戶新線程時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadLoginCheckFunc()", "建立登入用戶" + DataTerminal + "-" + DataTerminalName + "新線程時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                    }
                                }

                                #endregion

                                break;
                        }
                    }
                    else if (DataType == "WS" && DataTerminal.Length > 0)
                    {
                        //LogHelper.WriteLog("StartUp()", "手機端用戶: " + DataTerminal + "-" + DataTerminalName + " 請求登錄");

                        #region " Web端登錄 "

                        UserID = DataTerminal; // 用戶帳號
                        bool Passed = true;
                        //Socket curSkt = _ws_transmit_tb[DataTerminal] as Socket;
                        UserSocket User = _ws_transmit_tb[DataTerminal] as UserSocket;
                        if (User != null)
                        {
                            Socket curSkt = User.Socket;

                            #region " 發送離線 "
                            try
                            {
                                byte[] msg = WebConvertMethod.ConvertMsgToByte("00", "7", DataTerminal, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper());

                                //如果2秒內得不到之前登陸的對象,就直接干掉
                                //否則此帳號將永遠無法登錄
                                if (Monitor.TryEnter(curSkt, 2000))
                                {
                                    try
                                    {
                                        //向用戶本人發送離線
                                        curSkt.Send(msg);
                                        //SendData(curSkt, msg);
                                    }
                                    catch
                                    { }
                                    finally
                                    {
                                        Monitor.Exit(curSkt);
                                    }
                                }
                                else
                                {
                                    //如果到這里說明之前登陸的對象已經死鎖                                            
                                }
                                //curSkt.Send(msg);

                                UpdateUserLog(UserID, "0", "1", "因相同帳號再次登錄而強制離線.");

                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):default", "相同帳號異地登陸:" + DataTerminal + " " + DataTerminalName);
                                //LogHelper.WriteLog("StartUp()", "手機端相同帳號重複登陸:" + DataTerminal + "-" + DataTerminalName);
                            }
                            catch (SocketException ex)
                            {
                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):default", "轉發發送離線消息時:" + ex.Message);
                                //LogHelper.WriteLog("StartUp()", "轉發發送離線消息時" + (ex != null ? ex.Message : ""));
                                LogHelper.WriteLog("StartUp()", "轉發手機用戶" + UserID + "離線消息時:" + (ex != null ? ex.Message : ""));
                            }
                            try
                            {
                                if (curSkt.Connected)
                                {
                                    curSkt.Shutdown(SocketShutdown.Both);
                                    //curSkt.Disconnect(false);
                                }
                                curSkt.Close();
                                curSkt = null;

                                Thread thread = _ws_thread_tb[DataTerminal] as Thread;
                                if (thread != null)
                                {
                                    thread.Abort();
                                    //線程池不會被遍歷,不鎖.
                                    _ws_thread_tb.Remove(DataTerminal);
                                }
                                lock (_ws_transmit_tb.SyncRoot)
                                    _ws_transmit_tb.Remove(DataTerminal);
                            }
                            catch (SocketException ex)
                            {
                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "嘗試關閉用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                LogHelper.WriteLog("StartUp()", "嘗試關閉手機用戶" + DataTerminal + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                            }
                            #endregion
                        }
                        // 驗證是否為唯一用戶
                        if (_ws_transmit_tb.Count != 0 && _ws_transmit_tb.ContainsKey(UserID))
                        {
                            try
                            {
                                byte[] msg = WebConvertMethod.ConvertMsgToByte("登錄失敗.", "3", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper());
                                lock (newClient)
                                {
                                    newClient.Send(msg);
                                    //SendData(newClient, msg);
                                }
                                LogHelper.WriteLog("StartUp()", "手機端" + DataTerminal + "登錄失敗");
                            }
                            catch (SocketException ex)
                            {
                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():驗證是否為唯一用戶", "發送登陸失敗信息時:" + ex.Message);
                                LogHelper.WriteLog("StartUp()", "發送登陸失敗信息時" + (ex != null ? ex.Message : ""));
                            }
                        }
                        else
                        {
                            // 服務器開放登錄功能
                            try
                            {
                                byte[] msg = WebConvertMethod.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper());
                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                lock (newClient)
                                {
                                    newClient.Send(msg);
                                    //SendData(newClient, msg);
                                }
                            }
                            catch (Exception ex)
                            {
                                Passed = false;
                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():服務器開放登錄功能", "發送登陸成功信息時:" + ex.Message);
                                LogHelper.WriteLog("StartUp()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                            }

                            if (Passed)
                            {
                                //創建連接對象
                                User = new UserSocket();
                                User.ID = UserID;
                                User.Socket = newClient;
                                User.State = UserSocket.UserStates.Online;

                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        #region " 獲得當前用記的所有聯絡人并向他們推送用戶上線消息 "

                                        StateNotifyQueue.Enqueue(new List<object>() { User, "1" });

                                        //DataTable ContactsList = GetContacts(conn, UserID);
                                        //if (ContactsList.Rows.Count > 0)
                                        //{
                                        //    foreach (DataRow Contact in ContactsList.Rows)
                                        //    {
                                        //        //加入聯絡人(防呆自己加自己)
                                        //        if (User.ID != Contact["contact_id"].ToString())
                                        //            User.Contacts.Add(Contact["contact_id"].ToString());
                                        //    }
                                        //    //改為獨立線程來發
                                        //    //如果此聯絡人在線就通知他(她)當前用戶上線了
                                        //    //try
                                        //    //{
                                        //    //    Thread stateThread = new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc));
                                        //    //    stateThread.Start(User);
                                        //    //}
                                        //    //catch
                                        //    //{ }
                                        //    //如果此聯絡人在線就通知他(她)當前用戶上線了
                                        //    SendUserState(User);
                                        //}
                                        //ContactsList.Dispose();
                                        //ContactsList = null;

                                        #endregion

                                        #region " 發送所有未讀訊息(手機版暫時不推未讀取消息) "

                                        //DataTable MsgsList = GetUnreadMsgs(conn, UserID);
                                        //if (MsgsList.Rows.Count > 0)
                                        //{
                                        //    if (newClient != null)
                                        //    {
                                        //        foreach (DataRow UnreadMsg in MsgsList.Rows)
                                        //        {
                                        //            // 發給登錄人
                                        //            DateTime MsgDT = DateTime.Parse(UnreadMsg["msg_date"].ToString() + " " + UnreadMsg["msg_time"].ToString());
                                        //            byte[] rtnMsg = WebConvertMethod.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                        //                                                              UnreadMsg["td_no"].ToString().Length > 0 ? "4" : "U",
                                        //                                                              UnreadMsg["msg_from"].ToString(),
                                        //                                                              UnreadMsg["user_name"].ToString(),
                                        //                                                              UnreadMsg["td_no"].ToString(),
                                        //                                                              MsgDT,
                                        //                                                              UnreadMsg["msg_guid"].ToString());
                                        //            lock (newClient)
                                        //            {
                                        //                newClient.Send(rtnMsg);
                                        //            }
                                        //        }

                                        //        // 更新為已讀 
                                        //        conn.ExecuteSQL("update a set a.msg_state='1' from lrmsgstate a where a.msg_to='" + UserID + "' and a.msg_state='0'");
                                        //    }
                                        //}
                                        //MsgsList.Dispose();
                                        //MsgsList = null;

                                        #endregion
                                    }
                                    catch (SocketException ex)
                                    {
                                        //test
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                        LogHelper.WriteLog("StartUp()", "向Mobile端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                                    }

                                    try
                                    {
                                        //更新用戶狀態
                                        DoUpdateUserLog(conn, UserID, "0", "1", "登錄");
                                        DoUpdateUserState(conn, UserID, "1"); //上線中
                                    }
                                    catch (Exception ex)
                                    {
                                        Passed = false;
                                        LogHelper.WriteLog("StartUp()", "更新Mobile端用戶:" + DataTerminal + "狀態." + (ex != null ? ex.Message : ""));
                                    }
                                    conn.CloseConnection();
                                }

                                if (Passed)
                                {
                                    // 將新連接加入轉發表並創建線程為其服務
                                    lock (_ws_transmit_tb.SyncRoot)
                                    {
                                        //_ws_transmit_tb.Add(UserID, newClient);
                                        _ws_transmit_tb.Add(UserID, User);
                                    }
                                    //LogHelper.WriteLog("StartUp()", "手機端" + DataTerminal + "已添加到在線用戶列表");

                                    try
                                    {
                                        Thread clientThread = new Thread(new ParameterizedThreadStart(WebThreadFunc));
                                        //加入哈希表
                                        _ws_thread_tb.Add(UserID, clientThread);
                                        //clientThread.Start(userName);
                                        clientThread.Start(UserID);
                                        //LogHelper.WriteLog("StartUp()", "手機端" + DataTerminal + "-" + DataTerminalName + "登錄成功");
                                    }
                                    catch (Exception ex)
                                    {
                                        try
                                        {
                                            // 發生錯誤時移除連接
                                            lock (_ws_transmit_tb.SyncRoot)
                                            {
                                                //_transmit_tb.Add(UserID, newClient);
                                                _ws_transmit_tb.Remove(UserID);
                                            }
                                        }
                                        catch
                                        { }
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp():開啟新線程", "建立登入用戶新線程時:" + ex.Message);
                                        LogHelper.WriteLog("StartUp()", "建立登入用戶" + DataTerminal + "-" + DataTerminalName + "新線程時:" + (ex != null ? ex.Message : ""));
                                    }
                                }
                            }
                        }
                        //需不需要干掉自己?
                        //Thread.CurrentThread.Abort();
                        #endregion
                    }
                    else
                    {
                        // 無效訊息-丟棄
                        try
                        {
                            if (newClient.Connected)
                            {
                                newClient.Shutdown(SocketShutdown.Both);
                                //clientSkt.Disconnect(false);
                            }
                            newClient.Close();
                            //LogHelper.WriteLog("StartUp()", "無效登錄請求被丟棄");
                        }
                        catch (SocketException ex)
                        {
                            //clsClientLog.WriteLog(clsClientLog.LogType.System, "CloseClientSocket", "嘗試關閉一個異常的Socket連接時出現問題:" + ex.Message);
                            LogHelper.WriteLog("ThreadLoginCheckFunc", "嘗試關閉一個無法識別的Socket連接請求時出現問題:" + (ex != null ? ex.Message : ""));
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("ThreadLoginCheckFunc", "用戶登錄時發生錯誤:" + (ex != null ? ex.Message : ""));
                }
                finally
                {
                    // 2016/02/27
                    // 回收到隊列
                    LoginThreadsQueue.Enqueue(LoginThread);
                    //LogHelper.WriteLog("ThreadLoginCheckFunc", "回收登錄線程[" + LoginThread.ManagedThreadId.ToString() + "]");
                }
            }


            ////需不需要干掉自己?
            //try
            //{
            //    Thread.CurrentThread.Abort();
            //}
            //catch
            //{ }
        }
示例#2
0
        /// <summary>
        /// 發送用戶狀態
        /// </summary>
        /// <param name="User"></param>
        /// <param name="UserState"></param>
        private void SendUserState(UserSocket User, string UserState)
        {
            if (_transmit_tb == null)
                return;
            if (User == null)
                return;
            if (User.Contacts.Count > 0)
            {
                try
                {
                    //0=空閒|1=上線|2=離開|3=忙碌|4=不要打擾|5=隱身|6=離線|7=簽名
                    //List<byte[]> msgs = ConvertMethod.ConvertMsgToByte(User.Signature, "S", User.ID, (User.ChangeSignature ? "7" : ((int)User.State).ToString()), "", "", "");
                    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte(User.Signature, "S", User.ID, UserState, "", "", "");
                    //Test
                    //LogHelper.WriteLog("SendUserState", "準備把" + User.ID + "的狀態" + UserState + "推送給聯絡人...");
                    int count = 0;
                    foreach (string contactID in User.Contacts)
                    {
                        //防止自己是自己的好友,給自己發狀態

                        #region " PC端用戶 "

                        if (_transmit_tb.ContainsKey(contactID) && contactID != User.ID)
                        {
                            //PC用戶
                            try
                            {
                                UserSocket Contact = _transmit_tb[contactID] as UserSocket;
                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                if (Contact != null)
                                {
                                    if (Contact.Socket != null)
                                    {
                                        if (Contact.Socket.Connected)
                                        {
                                            lock (Contact.Socket)
                                            {
                                                //Test
                                                //3秒不發不出去就跳過
                                                Contact.Socket.SendTimeout = 3000;
                                                try
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        Contact.Socket.Send(msg);
                                                        //SendData(Contact.Socket, msg);
                                                    }
                                                    count++;
                                                }
                                                catch (SocketException ex)
                                                {
                                                    throw ex;
                                                }
                                                finally
                                                {
                                                    Contact.Socket.SendTimeout = 0;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (SocketException ex)
                            {
                                // 可能掉線了,放他一馬.
                                LogHelper.WriteLog("SendUserState", "向聯絡人:" + contactID + "發送登錄用戶" + User.ID + "的狀態時出現問題." + (ex != null ? ex.Message : ""));
                            }
                        }

                        #endregion

                        #region " Mobile端用戶 "

                        if (_mobile_transmit_tb.ContainsKey(contactID) && contactID != User.ID)
                        {
                            //Mobile用戶
                            try
                            {
                                UserSocket Contact = _mobile_transmit_tb[contactID] as UserSocket;
                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                if (Contact != null)
                                {
                                    if (Contact.Socket != null)
                                    {
                                        if (Contact.Socket.Connected)
                                        {
                                            lock (Contact.Socket)
                                            {
                                                //Test
                                                //3秒不發不出去就跳過
                                                Contact.Socket.SendTimeout = 3000;
                                                try
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        Contact.Socket.Send(msg);
                                                        //SendData(Contact.Socket, msg);
                                                    }
                                                    count++;
                                                }
                                                catch (SocketException ex)
                                                {
                                                    throw ex;
                                                }
                                                finally
                                                {
                                                    Contact.Socket.SendTimeout = 0;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (SocketException ex)
                            {
                                // 可能掉線了,放他一馬.
                                LogHelper.WriteLog("SendUserState", "向聯絡人:" + contactID + "發送登錄用戶" + User.ID + "的狀態時出現問題." + (ex != null ? ex.Message : ""));
                            }
                        }

                        #endregion

                        //else if (_ws_transmit_tb.ContainsKey(contactID))
                        //{
                        //    //手機用戶
                        //}
                    }
                    //Test
                    //LogHelper.WriteLog("SendUserState", "成功向" + count.ToString() + "位聯絡人推送了" + User.ID + "的狀態:" + UserState);
                    //if(User.ChangeSignature)
                    //    User.ChangeSignature = false; //復位
                }
                catch
                { }
            }
        }
示例#3
0
 private void ProcessWebUserState(UserSocket User)
 {
     if (User == null)
         return;
     using (SQLHelper conn = new SQLHelper(DBInfo))
     {
         conn.OpenConnection();
         try
         {
             //通知在線的聯絡人當前用戶改變了狀態
             User.SetUserState("6");
             DoUpdateUserLog(conn, User.ID, "1", "1", "Mobile端登出");
             //如果PC端沒在線就通知聯絡人此人離線了
             UserSocket PCUser = _transmit_tb[User.ID] as UserSocket;
             if (PCUser == null)
             {
                 StateNotifyQueue.Enqueue(new List<object>() { User, ((int)User.State).ToString() });
                 //SendUserState(User);
                 //改為獨立線程來發
                 //如果此聯絡人在線就通知他(她)當前用戶上線了
                 //try
                 //{
                 //    Thread stateThread = new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc));
                 //    stateThread.Start(User);
                 //}
                 //catch
                 //{ }
                 DoUpdateUserState(conn, User.ID, "6"); //離線
             }
             conn.CloseConnection();
         }
         catch
         {
             conn.CloseConnection();
         }
     }
 }