Example #1
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="UserID"></param>
 /// <param name="conn"></param>
 /// <param name="logType">0=login;1=logout;2=signature</param>
 /// <param name="logDevice"></param>
 private void UpdateUserLog(string UserID, string logType, string logDevice, string logText)
 {
     using (SQLHelper conn = new SQLHelper(DBInfo))
     {
         conn.OpenConnection();
         try
         {
             DoUpdateUserLog(conn, UserID, logType, logDevice, logText);
             conn.CloseConnection();
         }
         catch (Exception ex)
         {
             conn.CloseConnection();
             throw ex;
         }
     }
 }
Example #2
0
        //2016/03/03
        /// <summary>
        /// 更新數據類群信息
        /// </summary>
        private void UpdateVDataThreadFunc()
        {
            //Test
            //VDataQueue.Enqueue("iemis.UpdateVData 'D151000001',N'這是一條測試數據,这是一条测试数据555.','2016/06/03','10:20:30'");
            bool TryOpenConn = false;
            int TryCount = 0;
            SQLHelper conn = new SQLHelper(DBInfo);
            try
            {
                conn.OpenConnection();

                while (true)
                {
                    Thread.Sleep(1000);
                    try
                    {
                        //當前設備數據更新隊列
                        ServerStatistics.CurentDeviceData_Queue = VDataQueue.Count;
                        //最高設備數據更新隊列
                        if (ServerStatistics.MaxDeviceData_Queue < ServerStatistics.CurentDeviceData_Queue)
                            ServerStatistics.MaxDeviceData_Queue = ServerStatistics.CurentDeviceData_Queue;

                        if (TryOpenConn)
                        {
                            try
                            {
                                conn.OpenConnection();
                                TryOpenConn = false;
                                //成功连接
                                LogHelper.WriteLog("UpdateVDataThreadFunc()", "重新连接数据库成功.");
                                TryCount = 0;
                            }
                            catch
                            {
                                //尝试重新连接超过180次(3分钟内不恢复)
                                TryCount++;
                            }
                            if (TryCount > 180)
                            {
                                LogHelper.WriteLog("UpdateVDataThreadFunc()", "尝试重新连接数据库次数达到" + TryCount.ToString() + "次仍然无法成功,更新作业被迫中止.请检查数据库状态和网络连接.");
                                break;
                            }
                        }
                        while (VDataQueue.Count > 0)
                        {
                            conn.ExecuteSQL(VDataQueue.Dequeue().ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        //发生异常有可能是数据库连接断开.标记下一次执行时尝试重新连接
                        TryOpenConn = true;
                        LogHelper.WriteLog("UpdateVDataThreadFunc()", "更新數據類群信息時:" + (ex != null ? ex.Message : ""));
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("UpdateVDataThreadFunc()", "更新數據類群信息時:" + (ex != null ? ex.Message : ""));
            }
            finally
            {
                if (conn != null)
                    conn.CloseConnection();
            }
        }
Example #3
0
        //private bool CloseBothSide(string curUserID, bool send711)
        //{
        //    //接收數據時發生異常,被置空.從哈希表中移除
        //    try
        //    {
        //        #region " 一方異常斷開則通知另一方后自動斷開另一方 "

        //        string tChannelGUID = curUserID.Substring(0, curUserID.Length - 2);
        //        //發送人姓名(發起方和接聽方都記錄的相同名稱)
        //        string DataTerminalName = m_userToken.BindingUser.Name;

        //        //發送者ID-接收者ID-GUID-R/S
        //        string Target = "", sChannelID = "";
        //        if (curUserID.Substring(curUserID.Length - 1, 1) == "S")
        //        {
        //            Target = tChannelGUID + "-R";
        //            sChannelID = m_userToken.BindingUser.ReceiverID;
        //        }
        //        else
        //        {
        //            Target = tChannelGUID + "-S";
        //            sChannelID = m_userToken.BindingUser.SenderID;
        //        }

        //        //通話A方時長
        //        if (!send711)
        //        {
        //            //記錄日誌
        //            try
        //            {
        //                //S通道對象
        //                SocketUserToken TargetA = m_asyncSocketServer.PcUserTokenList[m_userToken.BindingUser.SenderID] as SocketUserToken;
        //                SocketUserToken TargetB = m_asyncSocketServer.PcUserTokenList[m_userToken.BindingUser.ReceiverID] as SocketUserToken;
        //                string SIP = "", DevSName = "", SMacAddr = "", RIP = "", DevRName = "", RMacAddr = "";
        //                if (TargetA != null && TargetA.BindingUser != null)
        //                {
        //                    SIP = TargetA.BindingUser.IP;
        //                    DevSName = TargetA.BindingUser.DevName;
        //                    SMacAddr = TargetA.BindingUser.MacAddr;
        //                }
        //                if (TargetB != null && TargetB.BindingUser != null)
        //                {
        //                    RIP = TargetB.BindingUser.IP;
        //                    DevRName = TargetB.BindingUser.DevName;
        //                    RMacAddr = TargetB.BindingUser.MacAddr;
        //                }
        //                UpdateAudioLog(m_userToken.BindingUser.SenderID, m_userToken.BindingUser.ReceiverID, 
        //                               m_userToken.ConnectDateTime, m_userToken.ActiveDateTime, tChannelGUID,
        //                               SIP, DevSName, SMacAddr, RIP, DevRName, RMacAddr);
        //            }
        //            catch
        //            { }
        //        }
                
        //        SocketUserToken TargetUser = m_asyncSocketServer.AudioCallTokenList[Target] as SocketUserToken;
        //        if (TargetUser != null)
        //        {
        //            //主動關閉T通道連接
        //            m_asyncSocketServer.CloseClientSocket(TargetUser);
        //        }
        //        //再用S通道通知對方7-11(由於對方連線異常斷開導致通話中斷.)
        //        if (send711)
        //        {
        //            base.PushMessage("",
        //                             ParseProtocol.ConvertMsgToByte("11", "7", curUserID, "AudioUser", "", tChannelGUID, "-1"),
        //                             sChannelID, m_asyncSocketServer.PcUserTokenList, "CloseBothSide");
        //        }
        //        else
        //        {
        //            //發送通話時長消息
        //            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
        //            {
        //                conn.OpenConnection();
        //                try
        //                {
        //                    // 記錄到數據庫中
        //                    string DataGUID = Guid.NewGuid().ToString().Replace("-", "").ToUpper();
        //                    string DataBody = "本次通話時長: " + (int)m_userToken.ActiveDateTime.Subtract(m_userToken.ConnectDateTime).TotalSeconds + "秒.";
        //                    string MsgNO = this.InsertMsg(conn, m_userToken.BindingUser.SenderID, DataBody, "", m_userToken.BindingUser.ReceiverID, "1", DataGUID, false, true);
        //                    if (MsgNO.Length > 0)
        //                    {
        //                        //開始發送
        //                        base.SendP2PMessage(m_userToken.BindingUser.SenderID, DataTerminalName, m_userToken.BindingUser.ReceiverID, DataBody, conn, DataGUID, MsgNO, "U");
        //                    }
        //                    conn.CloseConnection();
        //                }
        //                catch
        //                {
        //                    conn.CloseConnection();
        //                }
        //            }
        //        }
        //        #endregion
        //    }
        //    catch
        //    { }
        //    // 斷開發送者(S)
        //    //主動關閉連接
        //    //m_userToken.Closing = true;
        //    return false;
        //}

        /// <summary>
        /// 斷開T通道兩端用戶
        /// </summary>
        public override void ProcessUserDisconnected()
        {
            try
            {
                //即將斷開連接的用戶ID
                string curUserID = m_userToken.BindingUser.ID;
                //T通道GUID
                string tChannelGUID = curUserID.Substring(0, curUserID.Length - 2);
                //發送人姓名(發起方和接聽方都記錄的相同名稱)
                string DataTerminalName = m_userToken.BindingUser.Name;

                //發送者ID-接收者ID-GUID-R/S
                string Target = "", Role = "";
                if (curUserID.Substring(curUserID.Length - 1, 1) == "S")
                {
                    Target = tChannelGUID + "-R";
                    Role = "S";
                }
                else
                {
                    Target = tChannelGUID + "-S";
                    Role = "R";
                }

                if (Role == "S")
                {
                    #region " 記錄日誌 "

                    try
                    {
                        //S通道對象
                        SocketUserToken TargetA = m_asyncSocketServer.PcUserTokenList[m_userToken.BindingUser.SenderID] as SocketUserToken;
                        SocketUserToken TargetB = m_asyncSocketServer.PcUserTokenList[m_userToken.BindingUser.ReceiverID] as SocketUserToken;
                        string SIP = "", DevSName = "", SMacAddr = "", RIP = "", DevRName = "", RMacAddr = "";
                        if (TargetA != null && TargetA.BindingUser != null)
                        {
                            SIP = TargetA.BindingUser.IP;
                            DevSName = TargetA.BindingUser.DevName;
                            SMacAddr = TargetA.BindingUser.MacAddr;
                        }
                        if (TargetB != null && TargetB.BindingUser != null)
                        {
                            RIP = TargetB.BindingUser.IP;
                            DevRName = TargetB.BindingUser.DevName;
                            RMacAddr = TargetB.BindingUser.MacAddr;
                        }
                        UpdateAudioLog(m_userToken.BindingUser.SenderID, m_userToken.BindingUser.ReceiverID,
                                       m_userToken.ConnectDateTime, m_userToken.ActiveDateTime, tChannelGUID,
                                       SIP, DevSName, SMacAddr, RIP, DevRName, RMacAddr);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog("AudioCallProcessor.CloseBothSide", "記錄通話日誌時出錯:" + (ex != null ? ex.Message : ""));
                    }

                    #endregion
                }

                if (Role == "S")
                {
                    //發送通話時長消息
                    using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                    {
                        conn.OpenConnection();
                        try
                        {
                            // 記錄到數據庫中
                            int TotalSeconds = (int)m_userToken.ActiveDateTime.Subtract(m_userToken.ConnectDateTime).TotalSeconds;
                            int Hours = 0, Minutes = 0, Seconds = 0;
                            Seconds = TotalSeconds % 60;
                            Minutes = ((TotalSeconds - Seconds) / 60) % 60;
                            Hours = (TotalSeconds - Seconds) / 3600;
                            string DataGUID = Guid.NewGuid().ToString().Replace("-", "").ToUpper();
                            string DataBody = "本次通話時長: " + Hours.ToString().PadLeft(2, '0') + ":" + Minutes.ToString().PadLeft(2, '0') + ":" + Seconds.ToString().PadLeft(2, '0');
                            string MsgNO = this.InsertMsg(conn, m_userToken.BindingUser.SenderID, DataBody, "", m_userToken.BindingUser.ReceiverID, "1", DataGUID, false, true);
                            if (MsgNO.Length > 0)
                            {
                                //開始發送
                                base.SendP2PMessage(m_userToken.BindingUser.SenderID, DataTerminalName, m_userToken.BindingUser.ReceiverID, DataBody, conn, DataGUID, MsgNO, "U");
                            }
                            conn.CloseConnection();
                        }
                        catch (Exception ex)
                        {
                            conn.CloseConnection();
                            LogHelper.WriteLog("AudioCallProcessor.CloseBothSide", "發送通話時長時發生錯誤:" + (ex != null ? ex.Message : ""));
                        }
                    }
                }
            }
            catch
            { }
        }
Example #4
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="UserID"></param>
 /// <param name="conn"></param>
 /// <param name="State"></param>
 public void UpdateUserState(string UserID, string State)
 {
     using (SQLHelper conn = new SQLHelper(DBInfo))
     {
         conn.OpenConnection();
         try
         {
             DoUpdateUserState(conn, UserID, State);
             conn.CloseConnection();
         }
         catch (Exception ex)
         {
             conn.CloseConnection();
             throw ex;
         }
     }
 }
Example #5
0
        //2016/02/27
        /// <summary>
        /// 標記歷史消息為已讀
        /// </summary>
        private void MarkReadThreadFunc()
        {
            bool TryOpenConn = false;
            int TryCount = 0;
            SQLHelper conn = new SQLHelper(DBInfo);
            try
            {
                conn.OpenConnection();

                while (true)
                {
                    Thread.Sleep(1000);
                    try
                    {
                        //當前歷史消息標記已讀隊列
                        ServerStatistics.CurentMarkRead_Queue = MarkReadHistoryMsgQueue.Count;
                        //最高歷史消息標記已讀隊列
                        if (ServerStatistics.MaxMarkRead_Queue < ServerStatistics.CurentMarkRead_Queue)
                            ServerStatistics.MaxMarkRead_Queue = ServerStatistics.CurentMarkRead_Queue;

                        if (TryOpenConn)
                        {
                            try
                            {
                                conn.OpenConnection();
                                TryOpenConn = false;
                                //成功连接
                                LogHelper.WriteLog("MarkReadThreadFunc()", "重新连接数据库成功.");
                                TryCount = 0;
                            }
                            catch
                            {
                                //尝试重新连接超过180次(3分钟内不恢复)
                                TryCount++;
                            }
                            if (TryCount > 180)
                            {
                                LogHelper.WriteLog("MarkReadThreadFunc()", "尝试重新连接数据库次数达到" + TryCount.ToString() + "次仍然无法成功,更新作业被迫中止.请检查数据库状态和网络连接.");
                                break;
                            }
                        }
                        while (MarkReadHistoryMsgQueue.Count > 0)
                        {
                            conn.ExecuteSQL(MarkReadHistoryMsgQueue.Dequeue().ToString());
                        }
                    }
                    catch (Exception ex)
                    {
                        //发生异常有可能是数据库连接断开.标记下一次执行时尝试重新连接
                        TryOpenConn = true;
                        LogHelper.WriteLog("MarkReadThreadFunc()", "標記歷史消息為已讀:" + (ex != null ? ex.Message : ""));
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("MarkReadThreadFunc()", "標記歷史消息為已讀:" + (ex != null ? ex.Message : ""));
            }
            finally
            {
                if (conn != null)
                    conn.CloseConnection();
            }
        }
Example #6
0
        private bool DoPcMobileLogin(string UserID, string DataTerminalName, string DataGroup, string DataText, SocketUserToken userToken, SocketUserTokenList UserTokenList)
        {
            bool Passed = true, Done = false;
            SocketUserToken ExistsUser = UserTokenList[UserID];
            if (ExistsUser != null)
            {
                Socket curSkt = ExistsUser.ConnectSocket;
                string curIPAddress = ExistsUser.ConnectSocket.RemoteEndPoint.ToString();
                #region " 發送離線 "

                try
                {
                    List<byte[]> msgs = ParseProtocol.ConvertMsgToByte("00", "7", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                    //如果2秒內得不到之前登陸的對象,就直接干掉
                    //否則此帳號將永遠無法登錄
                    if (Monitor.TryEnter(curSkt, 2000))
                    {
                        try
                        {
                            //向用戶本人發送離線
                            foreach (byte[] msg in msgs)
                            {
                                //2016/05/19 test
                                ExistsUser.AsyncSendAgent.DoSendBuffer(msg);
                                //curSkt.Send(msg);
                                //SendData(curSkt, msg);
                            }
                        }
                        catch (SocketException ex)
                        {
                            LogHelper.WriteLog("DoPcMobileLogin()", "執行向" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 發送強制離線[不允許自動重連]消息時:" + (ex != null ? ex.Message : ""));
                        }
                        finally
                        {
                            Monitor.Exit(curSkt);
                        }
                    }
                    else
                    {
                        //如果到這里說明之前登陸的對象已經死鎖  
                        LogHelper.WriteLog("DoPcMobileLogin()", "嘗試使用Monitor.TryEnter鎖定" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 時失敗.");
                    }
                }
                catch (SocketException ex)
                {
                    LogHelper.WriteLog("DoPcMobileLogin()", "向" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 發送離線[不允許自動重連]消息時:" + (ex != null ? ex.Message : ""));
                }

                try
                {
                    //運行到這里時,有可能客戶端收到7-00之後主動斷開連接,則會觸發CloseClientSocket.
                    if (!ExistsUser.Closing)
                    {
                        //ExistsUser.Closing = true;
                        CloseClientSocket(ExistsUser);
                    }

                    LogHelper.WriteLog("DoPcMobileLogin", string.Format("因相同帳號再次登錄,強制先登錄的用戶{0} [{1}] 下線.", UserID, curIPAddress));

                    UpdateUserLog(UserID, "1", "0", "因相同帳號再次登陸而強制離線.", "", null);
                }
                catch (SocketException ex)
                {
                    LogHelper.WriteLog("DoPcMobileLogin()", "嘗試關閉" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                }

                #endregion
            }
            // 驗證是否為唯一用戶
            if (UserTokenList.ContainsKey(UserID))
            {
                //到這里說明前面強制離線沒有成功
                try
                {
                    List<byte[]> msgs = ParseProtocol.ConvertMsgToByte("登錄失敗.", "3", UserID, DataTerminalName, "", Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                    lock (userToken.ConnectSocket)
                    {
                        foreach (byte[] msg in msgs)
                        {
                            //同步發送
                            //2016/05/19 test
                            userToken.AsyncSendAgent.DoSendBuffer(msg);
                            //userToken.ConnectSocket.Send(msg);
                            //SendData(userToken.ConnectSocket, msg);
                        }
                    }
                    LogHelper.WriteLog("ProcessLogin()", DataGroup + "用戶:" + UserID + "登錄失敗");
                }
                catch (SocketException ex)
                {
                    LogHelper.WriteLog("ProcessLogin()", "發送登陸失敗信息時" + (ex != null ? ex.Message : ""));
                }
            }
            else
            {
                // 服務器開放登錄功能
                try
                {
                    List<byte[]> msgs = ParseProtocol.ConvertMsgToByte("登錄成功.", "2", UserID, DataTerminalName, DataGroup, Guid.NewGuid().ToString().Replace("-", "").ToUpper(), "");
                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                    lock (userToken.ConnectSocket)
                    {
                        foreach (byte[] msg in msgs)
                        {
                            //2016/05/19 test
                            userToken.AsyncSendAgent.DoSendBuffer(msg);
                            //userToken.ConnectSocket.Send(msg);
                            //SendData(userToken.ConnectSocket, msg);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Passed = false;
                    LogHelper.WriteLog("ProcessLogin()", "發送登錄成功信息時" + (ex != null ? ex.Message : ""));
                }

                if (Passed)
                {
                    //設置對象狀態
                    userToken.BindingUser = new User();
                    userToken.BindingUser.State = User.UserStates.Online;
                    userToken.BindingUser.Role = (DataGroup.Length > 0 ? User.UserRole.Mobile : User.UserRole.PC);
                    //移動設備登錄為: 
                    //iPhone = "IPHONE"
                    //iPad = "IPAD"
                    //Android Phone = "APHONE"
                    //Android Pad = "APAD"
                    switch (DataGroup.ToUpper())
                    {
                        case "IPHONE":
                            userToken.BindingUser.Mobile = User.UserMobileType.iPhone;
                            //iToken
                            userToken.BindingUser.iToken = DataText;
                            break;
                        case "IPAD":
                            userToken.BindingUser.Mobile = User.UserMobileType.iPad;
                            //iToken
                            userToken.BindingUser.iToken = DataText;
                            break;
                        case "APHONE":
                            userToken.BindingUser.Mobile = User.UserMobileType.AndroidPhone;
                            break;
                        case "APAD":
                            userToken.BindingUser.Mobile = User.UserMobileType.AndroidPad;
                            break;
                        default:
                            //默認PC
                            userToken.BindingUser.Mobile = User.UserMobileType.None;
                            break;
                    }
                    userToken.BindingUser.ID = UserID;
                    //Mac
                    userToken.BindingUser.MacAddr = DataTerminalName;
                    //IP
                    userToken.BindingUser.IP = ((IPEndPoint)userToken.ConnectSocket.RemoteEndPoint).Address.ToString();
                    //設備名稱
                    userToken.BindingUser.DevName = DataText;
                    Socket newClient = userToken.ConnectSocket;

                    string UserRegion = "";

                    using (SQLHelper conn = new SQLHelper(DBInfo))
                    {
                        conn.OpenConnection();
                        try
                        {
                            //取消日誌
                            //LogHelper.WriteLog("ProcessLogin()", "#5.登錄成功,準備截入聯絡人信息及推送未讀消息. " + UserID + " [" + userToken.ConnectSocket.RemoteEndPoint + "]");

                            #region " 載入聯絡人清單(聯絡人變更時應更新) "

                            DataTable ContactsList = GetContacts(conn, UserID);
                            if (ContactsList.Rows.Count > 0)
                            {
                                foreach (DataRow Contact in ContactsList.Rows)
                                {
                                    //加入聯絡人(防呆自己加自己)
                                    if (UserID != Contact["contact_id"].ToString())
                                        userToken.BindingUser.Contacts.Add(Contact["contact_id"].ToString());
                                }
                            }
                            ContactsList = null;

                            #endregion

                            #region " 當PC端和Mobile端未登錄的情況下才向其聯絡人推送用戶上線消息 "

                            if (!m_pcUserTokenList.ContainsKey(UserID) && !m_mobileUserTokenList.ContainsKey(UserID))
                                //ID,狀態,簽名,聯絡人清單,頭像數據
                                if (userToken.BindingUser.Contacts.Count > 0)
                                    StateNotifyQueue.Enqueue(new List<object>() { userToken.BindingUser.ID, "1", userToken.BindingUser.Signature, userToken.BindingUser.Contacts, null });

                            #endregion

                            #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());
                                            // 判斷個人消息還是群消息
                                            // 消息子類型(msg_doctype)(文字消息/文件消息) 
                                            // 0 = File 
                                            // 1 = Text Msg 
                                            // 2 = offline File
                                            // 3 = 截圖
                                            // 4 = email 
                                            // 5 = 抖動
                                            // 6 = 音頻
                                            List<byte[]> rtnMsgs = null;
                                            switch (UnreadMsg["msg_doctype"].ToString())
                                            {
                                                case "0":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                "P",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                "S",
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                case "2":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                "P",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                "O",
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                case "3":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte((byte[])UnreadMsg["msg_img"],
                                                                "I",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                UnreadMsg["td_no"].ToString(),
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                case "4":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                "M",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                UnreadMsg["td_no"].ToString(),
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                case "5":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                "Q",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                UnreadMsg["td_no"].ToString(),
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                case "6":
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte("Voice",
                                                                "R",
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                UnreadMsg["td_no"].ToString(),
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                      "");
                                                    break;
                                                default:
                                                    //1
                                                    string DataType = "";
                                                    if (UnreadMsg["msg_type"].ToString() == "0")
                                                    {
                                                        //小助手系統消息
                                                        DataType = "5";
                                                    }
                                                    else
                                                    {
                                                        DataType = UnreadMsg["td_no"].ToString().Length > 0 ? "4" : (UnreadMsg["msg_doctype"].ToString() == "0" ? "P" : "U");
                                                    }
                                                    rtnMsgs = ParseProtocol.ConvertMsgToByte(UnreadMsg["msg_text"].ToString(),
                                                                DataType,
                                                                UnreadMsg["msg_from"].ToString(),
                                                                UnreadMsg["user_name"].ToString(),
                                                                UnreadMsg["td_no"].ToString(),
                                                                MsgDT,
                                                                UnreadMsg["msg_guid"].ToString(),
                                                                UnreadMsg["msg_no"].ToString(),
                                                                        "");
                                                    break;
                                            }
                                            //if (UnreadMsg["msg_doctype"].ToString() == "3")
                                            //{
                                            //    rtnMsgs = ParseProtocol.ConvertMsgToByte((byte[])UnreadMsg["msg_img"],
                                            //                                            "I",
                                            //                                            UnreadMsg["msg_from"].ToString(),
                                            //                                            UnreadMsg["user_name"].ToString(),
                                            //                                            UnreadMsg["td_no"].ToString(),
                                            //                                            MsgDT,
                                            //                                            UnreadMsg["msg_guid"].ToString(),
                                            //                                            UnreadMsg["msg_no"].ToString(),
                                            //                                                  "");
                                            //}
                                            //else
                                            //{
                                            //    rtnMsgs = ParseProtocol.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)
                                                {
                                                    //2016/05/19 test
                                                    userToken.AsyncSendAgent.DoSendBuffer(msg);
                                                    //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'");
                                        }
                                        catch (Exception ex)
                                        {
                                            LogHelper.WriteLog("ProcessLogin()", "標識歷史信息為已讀時:" + (ex != null ? ex.Message : ""));
                                        }
                                    }
                                }
                                //Test
                                LogHelper.WriteLog("ProcessLogin()", "共向" + DataGroup + "用戶:" + userToken.BindingUser.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 = ParseProtocol.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)
                                                {
                                                    //2016/05/19 test
                                                    userToken.AsyncSendAgent.DoSendBuffer(msg);
                                                    //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("ProcessLogin()", "標識歷史系統消息為已讀時:" + (ex != null ? ex.Message : ""));
                                        }
                                    }
                                }
                                //Test
                                //LogHelper.WriteLog("ProcessLogin()", "共向用戶:" + User.ID + "推送" + MsgsList.Rows.Count.ToString() + "條歷史命令.");
                            }

                            #endregion

                            MsgsList.Dispose();
                            MsgsList = null;

                            #endregion

                            //得到用戶區域代號
                            try
                            {
                                UserRegion = conn.OpenDataTable("select user_region from lrtduser (nolock) where user_no='" + UserID + "'", CommandType.Text).Rows[0][0].ToString();
                            }
                            catch
                            {
                                UserRegion = "";
                            }
                        }
                        catch (SocketException ex)
                        {
                            //test
                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "StartUp()", "向PC端" + DataTerminal + "推送未讀信息時出錯." + (ex != null ? ex.Message : ""));
                            LogHelper.WriteLog("ProcessLogin()", "向" + DataGroup + "用戶:" + UserID + "推送未讀信息和系統消息時出錯." + (ex != null ? ex.Message : ""));
                        }

                        //更新用戶狀態
                        try
                        {
                            DoUpdateUserLog(conn, UserID, "0", ((int)userToken.BindingUser.Mobile).ToString(), DataGroup + "登錄", ((IPEndPoint)userToken.ConnectSocket.RemoteEndPoint).Address.ToString(), DataText, DataTerminalName, null);
                            DoUpdateUserState(conn, UserID, "1"); //上線中
                        }
                        catch (Exception ex)
                        {
                            Passed = false;
                            LogHelper.WriteLog("ProcessLogin()", "更新" + DataGroup + "用戶:" + UserID + "狀態." + (ex != null ? ex.Message : ""));
                        }

                        conn.CloseConnection();
                    }

                    //只推PC端用戶
                    if (Passed && DataGroup.Length == 0)
                    {
                        #region " 向PC客戶端推送平臺數據(在線人數等) "
                        try
                        {
                            List<byte[]> MsgToPC = ParseProtocol.ConvertMsgToByte(string.Format(SysMessage, ActiveUsersCount,
                                                                                                            OnlineUsersCount,
                                                                                                            RegisteredUsersCount,
                                                                                                            TodayMessagesCount,
                                                                                                            TotalMessagesCount),
                                                                                  "9", "", "", "", "", "");
                            //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                            lock (newClient)
                            {
                                foreach (byte[] msg in MsgToPC)
                                {
                                    //2016/05/19 test
                                    userToken.AsyncSendAgent.DoSendBuffer(msg);
                                    //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("ProcessLogin()", "向PC端" + UserID + "推送平臺數據(在線人數等)." + (ex != null ? ex.Message : ""));
                        }
                        #endregion

                        #region " 向PC客戶端推送系統公告 "
                        try
                        {
                            if (SysNotices.Count > 0 && UserRegion.Length > 0 && (SysNotices.ContainsKey(UserRegion) || SysNotices.ContainsKey("ALL")))
                            {
                                List<NoticeMsg> nMsgs;
                                // 全服廣播
                                object AllNotices = SysNotices["ALL"];
                                if (AllNotices != null)
                                {
                                    nMsgs = (List<NoticeMsg>)AllNotices;
                                    List<byte[]> MsgNotice;
                                    foreach (NoticeMsg nMsg in nMsgs)
                                    {
                                        MsgNotice = ParseProtocol.ConvertMsgToByte(nMsg.MsgText, "B", "1", nMsg.MsgSeq, "ALL", "", "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in MsgNotice)
                                            {
                                                //2016/05/19 test
                                                userToken.AsyncSendAgent.DoSendBuffer(msg);
                                                //newClient.Send(msg);
                                                //SendData(newClient, msg);
                                            }
                                        }
                                    }
                                }
                                // 區域廣播
                                object RegionNotices = SysNotices[UserRegion];
                                if (RegionNotices != null)
                                {
                                    nMsgs = (List<NoticeMsg>)RegionNotices;
                                    List<byte[]> MsgNotice;
                                    foreach (NoticeMsg nMsg in nMsgs)
                                    {
                                        MsgNotice = ParseProtocol.ConvertMsgToByte(nMsg.MsgText, "B", "1", nMsg.MsgSeq, UserRegion, "", "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (newClient)
                                        {
                                            foreach (byte[] msg in MsgNotice)
                                            {
                                                //2016/05/19 test
                                                userToken.AsyncSendAgent.DoSendBuffer(msg);
                                                //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("ProcessLogin()", "向PC端" + UserID + "推送系統公告." + (ex != null ? ex.Message : ""));
                        }
                        #endregion
                    }

                    if (Passed)
                    {
                        //添加到正在執行的列表中
                        if (UserTokenList.ContainsKey(UserID))
                        {
                            ExistsUser = UserTokenList[UserID];
                            if (ExistsUser != null)
                            {
                                try
                                {
                                    LogHelper.WriteLog("DoPcMobileLogin", string.Format("加入在線人員列表時發現已有同名帳號在里面,強制用戶{0} [{1}] 下線.", UserID, ExistsUser.ConnectSocket.RemoteEndPoint));

                                    if (!ExistsUser.Closing)
                                    {
                                        //ExistsUser.Closing = true;
                                        CloseClientSocket(ExistsUser);
                                    }
                                }
                                catch (SocketException ex)
                                {
                                    LogHelper.WriteLog("ProcessLogin()", "嘗試關閉" + DataGroup + "用戶" + UserID + "線程和Socket連接時出錯." + (ex != null ? ex.Message : ""));
                                }
                            }
                            //LogHelper.WriteLog("ProcessLogin()", "#5.加入在線人員列表時發現已有同名帳號在里面. " + UserID + " [" + userToken.ConnectSocket.RemoteEndPoint + "]");
                        }
                        UserTokenList.Add(UserID, userToken);
                        //取消日志
                        //LogHelper.WriteLog("ProcessLogin()", "#6.已加入到在線人員列表. " + UserID + " [" + userToken.ConnectSocket.RemoteEndPoint + "]");
                        //System.Diagnostics.Debug.WriteLine(UserID + " Logged in at " + DateTime.Now.ToString("HH:mm:ss:fff"));
                        Done = true;
                    }
                }
            }
            return Done;
        }
Example #7
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="UserID"></param>
 /// <param name="conn"></param>
 /// <param name="logType">0=login;1=logout;2=signature</param>
 /// <param name="logDevice"></param>
 public void UpdateUserLog(string UserID, string logType, string logDevice, string logText, string logIP, byte[] logAvatar)
 {
     using (SQLHelper conn = new SQLHelper(DBInfo))
     {
         conn.OpenConnection();
         try
         {
             DoUpdateUserLog(conn, UserID, logType, logDevice, logText, logIP, "", "", logAvatar);
             conn.CloseConnection();
         }
         catch (Exception ex)
         {
             conn.CloseConnection();
             throw ex;
         }
     }
 }
Example #8
0
        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                string SrvNOs = "";

                ListViewItem lvi = listSubSrvs.SelectedItems[0];
                //foreach (ListViewItem lvi in listSubSrvs.Items)
                //{
                    if (lvi.SubItems[1].Text == "0")
                    {
                        ClientSocket clientSocket = new ClientSocket(GetLX_IP(IP.Text), Convert.ToInt32(Port.Text));
                        clientSocket.Connect(true);
                        clientSocket.ReciveMsg -= subSrv_ReciveMsg;
                        clientSocket.ReciveMsg += subSrv_ReciveMsg;
                        clientSocket.GroupID = lvi.SubItems[0].Text;
                        clientSocket.Send("SubSrv logged in", "0", clientSocket.GroupID, "mac", "SUB", Guid.NewGuid().ToString().ToString().Replace("-", "").ToUpper());

                        if (SubServices.Contains(clientSocket.GroupID))
                        {
                            //斷開原來的連接
                            try
                            {
                                ClientSocket oldClientSocket = SubServices[clientSocket.GroupID] as ClientSocket;
                                oldClientSocket.Disconnect();
                                oldClientSocket.Dispose();
                            }
                            catch
                            { }
                            SubServices.Remove(clientSocket.GroupID);
                        }
                        SubServices.Add(clientSocket.GroupID, clientSocket);
                        //記錄已開啟的訂閱呺 
                        SrvNOs +=  "'" + lvi.SubItems[0].Text + "',";
                    }
                //}
                //更新訂閱號狀態
                if (SrvNOs.Length > 0)
                {
                    using (SQLHelper conn = new SQLHelper(DBAlias))
                    {
                        conn.OpenConnection();
                        try
                        {
                            SrvNOs = SrvNOs.Substring(0, SrvNOs.Length - 1);
                            // 標記為已讀                    
                            DateTime now = DateTime.Now;
                            string ymd = now.ToString("yyyy/MM/dd");
                            string time = now.ToString("HH:mm:ss");
                            conn.ExecuteSQL("update a set a.srv_state='1',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lxsubsrvs a where a.srv_no in (" + SrvNOs + ")");

                            conn.CloseConnection();
                        }
                        catch
                        {
                            conn.CloseConnection();
                        }
                    }
                }
                //刷新列表
                btnRefresh_Click(sender, e);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Example #9
0
        /// <summary>
        /// 群異動系統消息
        /// </summary>
        /// <param name="Sender"></param>
        /// <param name="ToGroup"></param>
        /// <param name="MsgGUID"></param>
        /// <param name="MsgText"></param>
        protected void SendGroupSysMessage(string Sender, string ToGroup, string MsgGUID, string MsgText)
        {
            // 抓出群成員
            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
            {
                conn.OpenConnection();
                try
                {
                    // 記錄到數據庫中
                    string MsgNO = this.InsertMsg(conn, Sender, MsgText, ToGroup, "", "0", MsgGUID, false, true);

                    DataTable UserList = conn.OpenDataTable("select a.msg_to from lrmsgstate a (nolock) where a.msg_no=" + MsgNO + " and a.msg_state='0'", CommandType.Text);
                    if (UserList.Rows.Count > 0)
                    {
                        string Users = "";
                        // PC 和 Mobile 要用到的信息.提前打包好,沒必要放到for循環里去做
                        List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(MsgText, "5", "", "", ToGroup, MsgGUID, MsgNO);
                        // Web 要用到的信息.提前打包好,沒必要放到for循環里去做 - 暫時不實現
                        //byte[] msgw = WebConvertMethod.ConvertMsgToByte(DataBody, "5", "", "", DataGroup, MsgNO);

                        foreach (DataRow User in UserList.Rows)
                        {
                            //有沒有必要PC和MOBLIE端各開個一個欄位來存放消息是否讀取的標記?

                            #region " PC Client "

                            Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.PcUserTokenList, "SendGroupSysMessage");

                            #endregion

                            #region " Mobile Client "

                            Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.MobileUserTokenList, "SendGroupSysMessage");

                            #endregion

                            #region " Web Client - 暫時不實現"

                            //recUser = _ws_transmit_tb[User["msg_to"].ToString()] as UserSocket;
                            //if (recUser != null)
                            //{
                            //    Socket userSkt = recUser.Socket;

                            //    try
                            //    {
                            //        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                            //        lock (userSkt)
                            //        {
                            //            userSkt.Send(msgw);
                            //            //SendData(userSkt, msg);
                            //        }
                            //        Users += "'" + User["msg_to"].ToString() + "',";
                            //    }
                            //    catch (SocketException ex)
                            //    {
                            //        LogHelper.WriteLog("SendGroupSysMessage", "手機用戶:" + User["msg_to"].ToString() + "異常斷開連接:" + (ex != null ? ex.Message : ""));
                            //        try
                            //        {
                            //            //掉線了,直接干掉.
                            //            if (userSkt.Connected)
                            //            {
                            //                userSkt.Shutdown(SocketShutdown.Both);
                            //                //userSkt.Disconnect(false);
                            //            }
                            //            userSkt.Close();

                            //            #region " 聯絡人狀態變更 "

                            //            //如果PC端沒在線就通知聯絡人此人離線了
                            //            ProcessWebUserState(recUser);

                            //            #endregion

                            //            lock (_ws_transmit_tb.SyncRoot)
                            //                _ws_transmit_tb.Remove(User["msg_to"].ToString());
                            //            Thread userThread = _ws_thread_tb[User["msg_to"].ToString()] as Thread;
                            //            userThread.Abort();
                            //            //線程池不會被遍歷,不鎖.
                            //            _ws_thread_tb.Remove(User["msg_to"].ToString());
                            //        }
                            //        catch
                            //        { }
                            //    }
                            //}
                            #endregion
                        }
                        // 去掉最後一個逗號
                        if (Users.Length > 0)
                        {
                            Users = Users.Substring(0, Users.Length - 1);
                            // 標記為已讀
                            DateTime now = DateTime.Now;
                            string ymd = now.ToString("yyyy/MM/dd");
                            string time = now.ToString("HH:mm:ss");
                            conn.ExecuteSQL("update a set a.msg_state='1',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lrmsgstate a where a.msg_no=" + MsgNO + " and a.msg_state='0' and a.msg_to in (" + Users + ")");
                        }
                    }
                    UserList.Dispose();
                    UserList = null;

                    conn.CloseConnection();

                    #region " 向發送者發送回執7-03 "

                    PushFeedback(MsgGUID, MsgNO);

                    #endregion

                    #region " 處理同帳號設備之間發送的消息漫遊 "

                    //處理同一帳號多個端登錄的轉發.
                    if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.PC ||
                        m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                    {
                        //來自PC端消息.
                        //檢查相同帳號Mobile(Web)端有沒有登錄,有就轉發一次.
                        #region " Mobile Client "

                        PushRoaming(Sender, ParseProtocol.ConvertMsgToByte(MsgText, "5", "", "", ToGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.MobileUserTokenList);

                        #endregion
                    }
                    if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.Mobile ||
                        m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                    {
                        //來自Mobile(Web)端消息.
                        //檢查相同帳號Web端有沒有登錄,有就轉發一次.
                        #region " PC Client "

                        PushRoaming(Sender, ParseProtocol.ConvertMsgToByte(MsgText, "5", "", "", ToGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList);

                        #endregion
                    }

                    #endregion
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
        }
Example #10
0
        private void btnRefresh_Click(object sender, EventArgs e)
        {
            listSubSrvs.Items.Clear();

            using (SQLHelper conn = new SQLHelper(DBAlias))
            {
                conn.OpenConnection();
                try
                {
                    string SQL = "select * from lxsubsrvs (nolock) where srv_device = '" + Device + "'";
                    DataTable Rec = conn.OpenDataTable(SQL, CommandType.Text);
                    conn.CloseConnection();

                    foreach (DataRow row in Rec.Rows)
                    {
                        ListViewItem lvi = new ListViewItem(new string[2] { row["srv_no"].ToString(), row["srv_state"].ToString() });
                        listSubSrvs.Items.Add(lvi);
                    }

                    Rec.Dispose();
                    Rec = null;
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
        }
Example #11
0
        private void MainUI_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                lock (SubServices.SyncRoot)
                {
                    foreach (DictionaryEntry de in SubServices)
                    {
                        ClientSocket subSrv = de.Value as ClientSocket;
                        if (subSrv != null && subSrv.Connected)
                        {
                            try
                            {
                                subSrv.Send("SubSrv logged out", "1", subSrv.GroupID, "mac", "SUB", Guid.NewGuid().ToString().ToString().Replace("-", "").ToUpper());
                                subSrv.Disconnect();
                                subSrv.ReciveMsg -= subSrv_ReciveMsg;
                                subSrv.Dispose();
                            }
                            catch
                            { }
                        }
                    }
                }
                using (SQLHelper conn = new SQLHelper(DBAlias))
                {
                    conn.OpenConnection();
                    try
                    {
                        // 標記為已讀                    
                        DateTime now = DateTime.Now;
                        string ymd = now.ToString("yyyy/MM/dd");
                        string time = now.ToString("HH:mm:ss");
                        conn.ExecuteSQL("update a set a.srv_state='0',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lxsubsrvs a where srv_device = '" + Device + "' and srv_state = '1'");

                        conn.CloseConnection();
                    }
                    catch
                    {
                        conn.CloseConnection();
                    }
                }
                SubServices.Clear();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Example #12
0
        private void btnStop_Click(object sender, EventArgs e)
        {
            try
            {
                ListViewItem lvi = listSubSrvs.SelectedItems[0];
                if (SubServices[lvi.SubItems[0].Text] != null)
                {
                    ClientSocket subSrv = SubServices[lvi.SubItems[0].Text] as ClientSocket;
                    if (subSrv != null && subSrv.Connected)
                    {
                        try
                        {
                            subSrv.Send("SubSrv logged out", "1", subSrv.GroupID, "mac", "SUB", Guid.NewGuid().ToString().ToString().Replace("-", "").ToUpper());
                            subSrv.Disconnect();
                            subSrv.ReciveMsg -= subSrv_ReciveMsg;
                            subSrv.Dispose();
                        }
                        catch
                        { }
                    }

                    using (SQLHelper conn = new SQLHelper(DBAlias))
                    {
                        conn.OpenConnection();
                        try
                        {
                            // 標記為已讀                    
                            DateTime now = DateTime.Now;
                            string ymd = now.ToString("yyyy/MM/dd");
                            string time = now.ToString("HH:mm:ss");
                            conn.ExecuteSQL("update a set a.srv_state='0',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lxsubsrvs a where srv_device = '" + Device + "' and srv_no ='" + lvi.SubItems[0].Text + "'");

                            conn.CloseConnection();
                        }
                        catch
                        {
                            conn.CloseConnection();
                        }
                    }
                    SubServices.Remove(lvi.SubItems[0].Text);
                    //刷新列表
                    btnRefresh_Click(sender, e);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
Example #13
0
        /// <summary>
        /// 處理命令
        /// </summary>
        /// <returns></returns>
        public override bool ProcessCommand(SocketUserToken userToken)
        {
            //開始解包
            DynamicBufferManager receiveBuffer = userToken.ReceiveBuffer;
            string curUserID = userToken.BindingUser.ID;
            string curDevice = (userToken.BindingUser.Role == User.UserRole.PC ? "PC客戶端" : "Mobile客戶端");
            try
            {
                //返回解包后的資料(返回數組 0=type ; 1=終端; 2=群號; 3=時間; 4=消息ID; 5=消息內容 6=終端姓名 7=消息系統編號 8=設置漫遊)
                int msgDataLength = 0;
                object[] ReceiveData = ParseProtocol.UnpackMsgPackage(receiveBuffer.Buffer, out msgDataLength);
                string DataType = ReceiveData[0].ToString();

                //如果數據類別為空就踢出
                if (DataType == "")
                {
                    LogHelper.WriteLog("PcProcessor.ProcessCommand", "讀取" + curDevice + "用戶: @<" + curUserID + " " + userToken.ConnectSocket.RemoteEndPoint + "> 數據時連接異常斷開.");
                    //主動關閉連接
                    //userToken.Closing = true;
                    return false;
                }

                string DataTerminal = ReceiveData[1].ToString();
                string DataGroup = ReceiveData[2].ToString();
                string DataGUID = ReceiveData[4].ToString();
                string DataBody = ((DataType != "I" && DataType != "R") ? ReceiveData[5].ToString() : "N/A"); // 非屏幕截圖時才有值
                byte[] DataImage = ((DataType == "I" || DataType == "R") ? (byte[])ReceiveData[5] : null); // 屏幕截圖時才有值
                string DataTerminalName = ReceiveData[6].ToString();

                //Added by Donnie on 2016/04/27
                //如果是換頭像也不會有值
                if (DataType == "S" && DataTerminalName == "8")
                {
                    DataBody = "N/A";
                    DataImage = (byte[])ReceiveData[5];
                }

                // 分類處理
                switch (DataType)
                {
                    case "1":
                        #region " 用戶離線 "

                        LogHelper.WriteLog("PcProcessor.ProcessCommand", curDevice + "用戶: @<" + curUserID + " " + userToken.ConnectSocket.RemoteEndPoint + "> 離線.");

                        #endregion

                        //主動關閉連接
                        //userToken.Closing = true;
                        return false;
                    case "5":
                        #region " 群(異動)系統訊息 "

                        base.SendGroupSysMessage(DataTerminal, DataGroup, DataGUID, DataBody);

                        #endregion

                        break;
                    case "6":
                        #region " 心跳包 "

                        base.DoAlive(DataTerminal, DataBody, DataType, DataGUID);

                        #endregion

                        break;
                    case "7":
                        #region " 控制臺消息(7-07/7-08) "

                        base.ProcessConsoleCommands(DataBody);

                        #endregion

                        break;

                    case "8":
                        #region " 發送在線用戶ID清單 "

                        base.PushOnlineUserList(DataGroup, DataType, DataGUID);

                        #endregion

                        break;

                    case "B":
                        #region " 系統廣播/公告 - 管理員專用 "
                        try
                        {
                            //DataTerminal:命令(1=播放;0=停止)
                            //DataTerminalName: 項次
                            //DataGroup: 區域(ALL=全服播放;代號=單區播放)
                            //DataBody: 公告內容

                            //using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                            //{
                            //    conn.OpenConnection();
                            //    try
                            //    {
                            //        if (conn.OpenDataTable("select uid from lrbroadcast (nolock) where region_id = '" + DataGroup + "' and bdc_seq = '" + DataTerminalName + "'", CommandType.Text).Rows.Count > 0)
                            //        {
                            //            //有資料
                            //            conn.ExecuteSQL("update a set a.bdc_cmd='" + DataTerminal + "',a.bdc_text=N'" + DataBody + "' from lrbroadcast a where a.region_id = '" + DataGroup + "' and a.bdc_seq = '" + DataTerminalName + "'");
                            //        }
                            //        else
                            //        {
                            //            //沒資料
                            //            if (DataTerminal == "1")
                            //            {
                            //                conn.ExecuteSQL("insert into lrbroadcast (region_id,bdc_seq,bdc_text,bdc_cmd) values('" + DataGroup + "','" + DataTerminalName + "',N'" + DataBody + "','" + DataTerminal + "')");
                            //            }
                            //        }
                            //        conn.CloseConnection();
                            //    }
                            //    catch
                            //    {
                            //        conn.CloseConnection();
                            //    }
                            //}

                            ////1.更新公告內容和區域
                            //lock (base.m_asyncSocketServer.SysNotices.SyncRoot)
                            //{
                            //    if (base.m_asyncSocketServer.SysNotices.ContainsKey(DataGroup))
                            //    {
                            //        //ALL 也會存里面
                            //        List<NoticeMsg> nMsgs = (List<NoticeMsg>)base.m_asyncSocketServer.SysNotices[DataGroup];
                            //        NoticeMsg nMsg = nMsgs.Find(delegate(NoticeMsg _msg) { return _msg.MsgSeq == DataTerminalName; });
                            //        if (nMsg != null)
                            //        {
                            //            if (DataTerminal == "1")
                            //            {
                            //                // 替換現有的公告
                            //                nMsg.MsgText = DataBody;
                            //            }
                            //            else
                            //            {
                            //                // 移除現有的公告
                            //                nMsgs.Remove(nMsg);
                            //                if (nMsgs.Count == 0)
                            //                {
                            //                    // 當前區域沒有公告了,將區域移除
                            //                    base.m_asyncSocketServer.SysNotices.Remove(DataGroup);
                            //                }
                            //            }
                            //        }
                            //        else
                            //        {
                            //            if (DataTerminal == "1")
                            //            {
                            //                // 新公告
                            //                nMsgs.Add(new NoticeMsg() { MsgSeq = DataTerminalName, MsgText = DataBody });
                            //            }
                            //        }
                            //    }
                            //    else
                            //    {
                            //        if (DataTerminal == "1")
                            //        {
                            //            //新公告
                            //            base.m_asyncSocketServer.SysNotices.Add(DataGroup, new List<NoticeMsg>() { new NoticeMsg() { MsgSeq = DataTerminalName, MsgText = DataBody } });
                            //        }
                            //    }
                            //}

                            //2.向區域內的用戶播放
                            base.SendSysNotice(DataTerminal, DataTerminalName, DataGroup, DataBody);
                        }
                        catch (Exception ex)
                        {
                            LogHelper.WriteLog("PcProcessor.ProcessCoommand", "發送服務器廣播時:" + (ex != null ? ex.Message : ""));
                        }

                        #endregion

                        break;

                    case "H":
                        #region " 發送服務器健康報告 "

                        try
                        {
                            //[#1]:120                   [PC端用戶]
                            //[#2]:12                    [移動端用戶]
                            //[#3]:10                    [訂閱號服務端]
                            //[#4]:12/50                 [空閒UserToken]
                            //[#5]:10                    [APP用戶]
                            //[#6]:2                     [文件傳送用戶]
                            //[#7]:0                     [歷史消息標記已讀隊列]
                            //[#8]:89                    [用戶狀態推送隊列]
                            //[#9]:0/10                  [空間狀態推送線程]
                            //[#10]:10                   [設備數據更新隊列]
                            //[#11]:10                   [語音通話客戶]
                            DataBody = "";

                            //[PC端用戶]
                            DataBody += "[#1]:" + m_asyncSocketServer.PcUserTokenList.Count.ToString() + "|";
                            //[移動端用戶]
                            DataBody += "[#2]:" + m_asyncSocketServer.MobileUserTokenList.Count.ToString() + "|";
                            //[訂閱號服務端]
                            DataBody += "[#3]:" + m_asyncSocketServer.SubServiceTokenList.Count.ToString() + "|";
                            //[空閒UserToken]
                            DataBody += "[#4]:" + m_asyncSocketServer.IdleUserTokenPool.Count.ToString() + "/" + m_asyncSocketServer.MaxServerLoading.ToString() + "|";
                            //[APP用戶]
                            DataBody += "[#5]:" + m_asyncSocketServer.AppUserTokenList.Count.ToString() + "|";
                            //[文件傳送用戶]
                            DataBody += "[#6]:" + m_asyncSocketServer.FileUserTokenList.Count.ToString() + "|";
                            //[歷史消息標記已讀隊列]
                            DataBody += "[#7]:" + m_asyncSocketServer.MarkReadHistoryMsgQueue.Count.ToString() + "|";
                            //[用戶狀態推送隊列]
                            DataBody += "[#8]:" + m_asyncSocketServer.StateNotifyQueue.Count.ToString() + "|";
                            //[空間狀態推送線程]
                            DataBody += "[#9]:" + m_asyncSocketServer.StateNofityThreadsQueue.Count.ToString() + "/" + m_asyncSocketServer.MaxStateNotifyThreads.ToString() + "|";
                            //[設備數據更新隊列]
                            DataBody += "[#10]:" + m_asyncSocketServer.VDataQueue.Count.ToString() + "|";
                            //[語音通話客戶]
                            DataBody += "[#11]:" + m_asyncSocketServer.AudioCallTokenList.Count.ToString();

                            List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(DataBody, DataType, DataTerminal, DataTerminalName, "", DataGUID);

                            //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                            lock (userToken.ConnectSocket)
                            {
                                foreach (byte[] msg in msgs)
                                {
                                    //2016/05/19 test
                                    userToken.AsyncSendAgent.DoSendBuffer(msg);
                                    //userToken.ConnectSocket.Send(msg);
                                    //base.SendData(userToken.ConnectSocket, msg);
                                }
                            }
                            //clsClientLog.WriteLog(clsClientLog.LogType.Info, "ThreadFunc(object obj):default", "成功向: " + _receiver + " 發送信息: " + _packetBuff);
                        }
                        catch (Exception ex)
                        {
                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送在線用戶ID清單時:" + ex.Message);
                            LogHelper.WriteLog("PcProcessor.ProcessCoommand", "發送服務器健康報告時時:" + (ex != null ? ex.Message : ""));
                        }

                        #endregion

                        break;
                    case "C":
                        #region " 群命令 "

                        // 抓出群成員
                        using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                        {
                            conn.OpenConnection();
                            try
                            {
                                // 記錄到數據庫中
                                //DateTime MsgDT = DateTime.Now;
                                string MsgNO = this.InsertCmd(conn, DataTerminal, DataBody, DataGroup, DataGUID);
                                if (MsgNO.Length > 0)
                                {
                                    // 向管理員發的命令不轉發
                                    if (DataGroup.Length > 0)
                                    {
                                        //系統將命令轉發給群成員(以發送者的帳號) 
                                        base.SendGroupCommand(DataTerminal, DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO);
                                    }
                                    // 轉發完再發回執
                                    // 向發送者發送回執7-03
                                    // 回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                    base.PushFeedback(DataGUID, MsgNO);
                                }
                                conn.CloseConnection();
                            }
                            catch
                            {
                                conn.CloseConnection();
                            }
                        }

                        #endregion

                        break;
                    case "D":
                        #region " 撤回消息 "
                        //0001D發送人帳號(50b)接收對象類別(U=人;G=群)(60b)接收人/接收群(50b)GMT時間(20b)要撤回消息的GUID(32b)訊息流水號(20b)
                        using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                        {
                            conn.OpenConnection();
                            try
                            {
                                // 記錄到數據庫中(1=撤回,M=消息lrmsg)
                                string MsgNO = this.InsertSysMsg(conn, DataTerminal, DataBody, "1", "M", (DataTerminalName == "G" ? DataGroup : ""), (DataTerminalName == "U" ? DataGroup : ""), DataGUID);
                                if (MsgNO.Length > 0)
                                {
                                    //系統將訊息轉發給群成員(以發送者的帳號) 
                                    base.SendGroupSysBroadcast("D", "1", "M", DataTerminal, DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO);
                                    // 轉發完再發回執
                                    // 向發送者發送回執7-03
                                    base.PushFeedback(DataGUID, MsgNO);

                                }
                                conn.CloseConnection();
                            }
                            catch
                            {
                                conn.CloseConnection();
                            }
                        }
                        #endregion

                        break;
                    case "G":
                    case "L":

                        #region " 群組訊息(G=Push / L=Pull) "

                        base.SendGroupBroadcast(DataTerminal, DataGroup, DataBody, DataTerminalName, DataGUID, DataType == "G");

                        #endregion

                        break;
                    case "I":
                        #region " 轉發屏幕截圖 "

                        //DataTerminal是接收人帳號(對人)
                        //DataTerminal是發送人帳號(對群)
                        //DataTerminalName是發送人姓名
                        base.SendImage(DataTerminal, DataGroup, DataImage, DataTerminalName, DataGUID);

                        #endregion

                        break;

                    case "U": //人對人信息
                    case "T": //測試工具使用
                        #region " 用戶訊息 "

                        //別搞暈了
                        //DataTerminal是接收人帳號
                        //DataTerminalName是發送人姓名
                        using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                        {
                            conn.OpenConnection();
                            try
                            {
                                // 記錄到數據庫中
                                //DateTime MsgDT = DateTime.Now;
                                //T=測試用(超哥神器)
                                string MsgNO = this.InsertMsg(conn, curUserID, DataBody, "", DataTerminal, "1", DataGUID, DataType == "T", true);
                                if (MsgNO.Length > 0)
                                {
                                    //開始發送
                                    base.SendP2PMessage(curUserID, DataTerminalName, DataTerminal, DataBody, conn, DataGUID, MsgNO, DataType);

                                    // 轉發完再發回執
                                    // 向發送者發送回執7-03
                                    base.PushFeedback(DataGUID, MsgNO);
                                }
                                conn.CloseConnection();
                            }
                            catch
                            {
                                conn.CloseConnection();
                            }
                        }

                        #endregion

                        break;
                    case "Q": //抖動
                        #region " 抖動 "
                        //DataTerminal是接收人帳號
                        //DataTerminalName是發送人姓名
                        using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                        {
                            conn.OpenConnection();
                            try
                            {
                                // 記錄到數據庫中
                                //DateTime MsgDT = DateTime.Now;
                                string MsgNO = this.InsertMsg(conn, curUserID, DataBody, "", DataTerminal, "1", "", "5", "0", DataGUID, false, true);
                                if (MsgNO.Length > 0)
                                {
                                    //開始發送
                                    base.SendP2PMessage(curUserID, DataTerminalName, DataTerminal, DataBody, conn, DataGUID, MsgNO, DataType);

                                    // 轉發完再發回執
                                    // 向發送者發送回執7-03
                                    base.PushFeedback(DataGUID, MsgNO);
                                }
                                conn.CloseConnection();
                            }
                            catch
                            {
                                conn.CloseConnection();
                            }
                        }
                        #endregion

                        break;

                    case "R":
                        #region " 轉發錄音 "

                        //DataTerminal是接收人帳號(對人)
                        //DataTerminal是發送人帳號(對群)
                        //DataTerminalName是發送人姓名
                        //ReceiveData[7].ToString()是語音時長
                        base.SendVoice(DataTerminal, DataGroup, DataImage, DataTerminalName, DataGUID, ReceiveData[7].ToString());

                        #endregion

                        break;

                    case "S":
                        #region " 聯絡人狀態變更 "
                        //通知在線的聯絡人當前用戶改變了狀態
                        //0=空閒|1=上線|2=離開|3=忙碌|4=不要打擾|5=隱身|6=離線|7=簽名|8=換頭像
                        userToken.BindingUser.SetUserState(DataTerminalName);
                        //特殊處理簽名操作
                        if (DataTerminalName == "7")
                        {
                            //User.ChangeSignature = true;
                            userToken.BindingUser.Signature = DataBody; //signature
                            m_asyncSocketServer.UpdateUserLog(curUserID, "2", "0", userToken.BindingUser.Signature, "", null);
                        }
                        else if (DataTerminalName == "8")
                        {
                            //Added by Donnie on 2016/04/27
                            // 變更頭像的處理
                            m_asyncSocketServer.UpdateUserLog(curUserID, "3", "0", "更新頭像", "", DataImage);
                        }

                        //Added by Donnie on 2016/04/27
                        //ID,狀態,簽名,聯絡人清單,頭像數據
                        if (userToken.BindingUser.Contacts.Count > 0)
                            m_asyncSocketServer.StateNotifyQueue.Enqueue(new List<object>() { curUserID, DataTerminalName, userToken.BindingUser.Signature, userToken.BindingUser.Contacts, DataImage });

                        //Added by Donnie on 2016/04/27
                        //簽名各頭像變更不會影響在線狀態
                        if (DataTerminalName != "7" && DataTerminalName != "8")
                            m_asyncSocketServer.UpdateUserState(curUserID, DataTerminalName); //state
                        #endregion

                        break;
                    case "P":
                        #region " 請求發送文件和同意接受文件 "
                        //發起發送文件請求: 0019P接收人帳號(50b)發起人姓名(60b)S(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                        //接收人同意請求:   0019P發起人帳號(50b)接收人姓名(60b)R(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                        //包體: 文件名|大小|文件完整路徑
                        //接收方同意接收的請求等到接收方T通道建立完成再轉發給發送方
                        if (DataGroup != "R" && DataGroup.Length > 0)
                        {
                            switch (DataGroup)
                            {
                                case "Q":
                                    //斷開T通道的對象
                                    //0019P發起人帳號(50b)S(60b)Q(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                    //0019P接收人帳號(50b)R(60b)Q(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                    if (DataTerminalName == "R")
                                        break; //不再主動斷開接收端(R)T通道連接,由客戶端自主斷開.
                                    string TID = DataGUID + "-" + DataTerminalName;
                                    //LogHelper.WriteLog("ThreadFunc", "準備斷開:" + TID + "的連接...");
                                    SocketUserToken TSocket = m_asyncSocketServer.FileUserTokenList[TID] as SocketUserToken;

                                    if (TSocket != null)
                                    {
                                        //LogHelper.WriteLog("PcProcessor.ProcessCommand", "從S通道斷開:" + TID + ".");
                                        try
                                        {
                                            //主動關閉連接
                                            //TSocket.Closing = true;
                                            m_asyncSocketServer.CloseClientSocket(TSocket);
                                        }
                                        catch
                                        {
                                            LogHelper.WriteLog("CloseClientSocket", "無法從S通道斷開:" + TID + ",可能已從T通道斷開.");
                                        }
                                    }
                                    else
                                    {
                                        LogHelper.WriteLog("PcProcessor.ProcessCommand", "沒有找到:" + TID + ".");
                                    }
                                    break;
                                default:
                                    string MsgNO = base.ProcessTransferFileRequest(curUserID, DataType, DataTerminal, DataGroup, DataGUID, DataBody, DataTerminalName);
                                    // 向發送者發送回執7-03
                                    base.PushFeedback(DataGUID, MsgNO);

                                    break;
                            }
                        }
                        #endregion

                        break;

                    case "K":
                        #region " 踢人7-06 "
                        //0010K踢出目標帳號(50b)空格(60)空格(60)時間(20b)GUID(32b)訊息流水號(20b)
                        //包體:P/M (P=PC端;M=移動端)
                        //向被踢者發送回執7-06

                        SocketUserToken KickTarget = m_asyncSocketServer.PcUserTokenList[DataTerminal] as SocketUserToken;
                        if (DataBody == "M")
                        {
                            KickTarget = m_asyncSocketServer.MobileUserTokenList[DataTerminal] as SocketUserToken;
                            //if (KickTarget == null)
                            //{
                            //    KickTarget = _mobile_transmit_tb[DataTerminal] as UserSocket;
                            //}
                        }
                        if (KickTarget != null)
                        {
                            Socket KickTargetSkt = KickTarget.ConnectSocket;
                            bool ForceKickOut = DataGroup == "F"; //為F表示從服務器端強制斷開
                            try
                            {
                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                List<byte[]> msgs = ParseProtocol.ConvertMsgToByte("06", "7", "", "", "", DataGUID, "");
                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                lock (KickTargetSkt)
                                {
                                    if (KickTargetSkt.Connected)
                                    {
                                        foreach (byte[] msg in msgs)
                                        {
                                            //2016/05/19 test
                                            KickTarget.AsyncSendAgent.DoSendBuffer(msg);
                                            //KickTargetSkt.Send(msg);
                                            //base.SendData(KickTargetSkt, msg);
                                        }
                                    }
                                }
                            }
                            catch (SocketException ex)
                            {
                                //客戶端異常,強踢
                                ForceKickOut = true;
                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                LogHelper.WriteLog("PcProcessor.ProcessCommand", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                            }

                            #region " 用戶在線就讓其自動登出,否則直接踢出 "
                            //開踢
                            if (ForceKickOut)
                            {
                                //主動關閉連接
                                //KickTarget.Closing = true;
                                m_asyncSocketServer.CloseClientSocket(KickTarget);
                            }
                            #endregion
                        }
                        else
                        {
                            //Kick FileTransferID
                            KickTarget = m_asyncSocketServer.FileUserTokenList[DataTerminal] as SocketUserToken;
                            if (KickTarget != null)
                            {
                                //主動關閉連接
                                //KickTarget.Closing = true;
                                m_asyncSocketServer.CloseClientSocket(KickTarget);
                            }
                        }

                        //通知管理員執行成功7-03
                        base.PushFeedback(DataGUID, "");

                        #endregion

                        break;

                    case "W":
                        #region " 訂閱號消息 "

                        if (DataGroup.Length > 0)
                        {
                            //用戶向訂閱號發命令
                            SendRequestToSubService(DataTerminal, DataGroup, DataBody, DataTerminalName, DataGUID, true);
                        }

                        #endregion

                        break;

                    case "X":
                        #region " 請求和接受語音通話 "
                        //發起請求: 0019X接收人帳號(50b)發起人姓名(60b)S(50b)GMT時間(20b)語音流的GUID(32b)訊息流水號(20b)空格(1b)
                        //接受請求: 0019X發起人帳號(50b)接收人姓名(60b)R(50b)GMT時間(20b)語音流的GUID(32b)訊息流水號(20b)空格(1b)  
                        //包體: 內容暫時沒用
                        //接收方同意接收的請求等到接收方T通道建立完成再轉發給發送方
                        if (DataGroup.Length > 0)
                        {
                            switch (DataGroup)
                            {
                                case "R":
                                    //不做任何動作
                                    break;
                                case "A":
                                    //斷開T通道的對象
                                    //0019X接收人帳號(50b)發起人姓名(60b)A(50b)GMT時間(20b)語音流的GUID(32b)訊息流水號(20b)空格(1b)
                                    //0019X發起人帳號(50b)接收人姓名(60b)A(50b)GMT時間(20b)語音流的GUID(32b)訊息流水號(20b)空格(1b)
                                    base.PushMessage("",
                                                     ParseProtocol.ConvertMsgToByte(DataBody, DataType, curUserID, "AudioUser", DataGroup, DataGUID, "-1"),
                                                     DataTerminal, m_asyncSocketServer.PcUserTokenList, "ProcessCommand-X");
                                    break;
                                default:
                                    base.ProcessAudioCallRequest(curUserID, DataType, DataTerminal, DataGroup, DataGUID, DataBody, DataTerminalName);
                                    break;
                            }
                        }
                        #endregion

                        break;

                    case "Z":
                        #region " 記錄登錄流量和耗時數據 "
                        //DataBody包體格式:
                        //類別A;流量(Byte);耗時(ms);開始(當地)日期(yyyy/MM/dd);開始(當地)時間(HH:mm:ss.fff);結束(當地)日期(yyyy/MM/dd);結束(當地)時間(HH:mm:ss.fff)|類別B;流量(Byte);耗時(ms);開始(當地)日期(yyyy/MM/dd);開始(當地)時間(HH:mm:ss.fff);結束(當地)日期(yyyy/MM/dd);結束(當地)時間(HH:mm:ss.fff)
                        //邏輯:
                        //根據帳號+IP抓到lrlxlog里此用戶最大UID作業log_uid
                        base.SaveLoginStatData(userToken, DataTerminal, DataBody);
                        #endregion

                        break;
                }
                //System.Diagnostics.Debug.WriteLine("清除:" + receiveBuffer.DataCount.ToString() + "個Byte.");
                //把已處理的數據從緩存里清除
                //receiveBuffer.Clear(receiveBuffer.DataCount);
                receiveBuffer.Clear(msgDataLength);
                //扣除已發完的包
                base.m_readyPackage--;

                //發完一個包后,如果DataCount>0說明有粘包數據,嘗試發送出去,否則會影響後面數據的發送效率.
                //如果粘包不是一個完整的數據包就返回去接收數據
                //while (receiveBuffer.DataCount > 0)
                //{
                //    try
                //    {
                //        ProcessCommand(userToken);
                //    }
                //    catch
                //    {
                //        // 繼續收
                //        return true;
                //    }
                //}
                if (base.m_readyPackage > 0)
                    return ProcessCommand(userToken);
                else
                    return true;
                //System.Diagnostics.Debug.WriteLine("剩餘:" + receiveBuffer.DataCount.ToString() + "個Byte.");
                //test
                //System.Diagnostics.Debug.WriteLine(DateTime.Now.ToLongTimeString() + " - " + DataType);
                //return true;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("PcProcessor.ProcessCommand", string.Format("執行" + curDevice + "用戶:{0}命令時時出錯:{1}.", "@<" + userToken.BindingUser.ID + " " + userToken.ConnectSocket.RemoteEndPoint + "> ", (ex != null ? ex.Message : "")));
                //主動關閉連接
                //userToken.Closing = true;
                return false;
            }
        }
Example #14
0
        /// <summary>
        /// 線程執行體,轉發消息(PC端)
        /// </summary>
        /// <param name="obj">傳遞給線程執行體的用戶名,用以與用戶通信</param>
        private void ThreadFunc(object obj)
        {
            if (obj == null) return;
            // 通過轉發表得到當前用戶套接字
            //Socket clientSkt = _transmit_tb[obj] as Socket;
            UserSocket User = _transmit_tb[obj] as UserSocket;
            if (User != null)
            {
                Socket clientSkt = User.Socket;
                while (true)
                {
                    try
                    {
                        //返回解包后的資料(返回數組 0=type ; 1=終端; 2=群號; 3=時間; 4=消息ID; 5=消息內容; 6=終端姓名)
                        object[] ReceiveData = ConvertMethod.UnMsgPackage(clientSkt);

                        string DataType = ReceiveData[0].ToString();

                        //如果數據類別為空就踢出
                        if (DataType == "")
                        {
                            LogHelper.WriteLog("ThreadFunc", "讀取用戶:" + obj.ToString() + "數據時連接異常斷開.");
                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):catch (SocketException)", "讀取用戶:" + obj.ToString() + "的數據時發生異常,斷開連接.");
                            //接收數據時發生異常,被置空.從哈希表中移除
                            try
                            {
                                try
                                {
                                    if (clientSkt.Connected)
                                    {
                                        clientSkt.Shutdown(SocketShutdown.Both);
                                        //clientSkt.Disconnect(false);
                                    }
                                    clientSkt.Close();

                                    #region " 聯絡人狀態變更 "
                                    //通知在線的聯絡人當前用戶改變了狀態
                                    //User.SetUserState("6");
                                    //UpdateUserLog(User.ID, "1", "0", "PC端異常登出");
                                    //如果手機端沒在線就通知聯絡人我離線了
                                    ProcessPCUserState(User);
                                    #endregion
                                }
                                catch (SocketException ex)
                                {
                                    //clsClientLog.WriteLog(clsClientLog.LogType.System, "CloseClientSocket", "嘗試關閉一個異常的Socket連接時出現問題:" + ex.Message);
                                    LogHelper.WriteLog("ThreadFunc", "嘗試關閉一個異常的Socket連接時出現問題:" + (ex != null ? ex.Message : ""));
                                }

                                lock (_transmit_tb.SyncRoot)
                                    _transmit_tb.Remove(obj);
                                //線程池不會被遍歷,不鎖.
                                _thread_tb.Remove(obj);
                            }
                            catch
                            { }
                            Thread.CurrentThread.Abort();
                            break; //如果執行到這里就跳出(一般到上一句就結束了)
                        }

                        string DataTerminal = ReceiveData[1].ToString();
                        string DataGroup = ReceiveData[2].ToString();
                        string DataGUID = ReceiveData[4].ToString();
                        string DataBody = (DataType != "I" ? ReceiveData[5].ToString() : "N/A"); // 非屏幕截圖時才有值
                        byte[] DataImage = (DataType == "I" ? (byte[])ReceiveData[5] : null); // 屏幕截圖時才有值
                        string DataTerminalName = ReceiveData[6].ToString();

                        //byte[] headerPacketBuff = new byte[_headerPacket];
                        ////接收包頭
                        //clientSkt.Receive(headerPacketBuff);
                        //string headerData = Encoding.UTF8.GetString(headerPacketBuff).TrimEnd('\0');
                        //int DataLen = ConvertMethod.Convert16To10(headerData.Substring(0, 4)); // 包體長度(16進制轉10進制)
                        //string DataType = headerData.Substring(4, 1);                          // 包類別
                        //string DataTerminal = headerData.Substring(5, 50).Replace(" ", "");      // 包終端
                        ////接收包體
                        //byte[] bodyPacketBuff = new byte[DataLen];
                        //clientSkt.Receive(bodyPacketBuff);
                        //string bodyData = Encoding.UTF8.GetString(bodyPacketBuff).TrimEnd('\0');
                        ////接收包尾
                        //byte[] tailPacketBuff = new byte[1];
                        //clientSkt.Receive(tailPacketBuff);
                        //string tailData = Encoding.UTF8.GetString(tailPacketBuff).TrimEnd('\0');

                        // 分類處理
                        switch (DataType)
                        {
                            case "1":
                                #region " 用戶離線 "

                                try
                                {
                                    //通知在線的聯絡人當前用戶離線了
                                    //User.State = UserSocket.UserStates.Offline;
                                    //UpdateUserLog(User.ID, "1", "0", "PC端登出");
                                    //如果手機端沒在線就通知聯絡人我離線了
                                    //DataGroup = ""; //TEST
                                    if (DataGroup.ToUpper() != "APP")
                                    {
                                        //普通用戶記錄
                                        ProcessPCUserState(User);
                                        LogHelper.WriteLog("ThreadFunc", "用戶:" + obj.ToString() + "離線.");
                                    }
                                    if (clientSkt.Connected)
                                    {
                                        clientSkt.Shutdown(SocketShutdown.Both);
                                        //clientSkt.Disconnect(false);
                                    }
                                    clientSkt.Close();

                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):catch (SocketException)", "用戶:" + obj.ToString() + "通知離線.");
                                }
                                catch (SocketException ex)
                                {
                                    if (DataGroup.ToUpper() != "APP")
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):catch (SocketException)", "用戶:" + obj.ToString() + "離線時發生錯誤:" + (ex != null ? ex.Message : ""));
                                        LogHelper.WriteLog("ThreadFunc", "用戶:" + obj.ToString() + "離線時發生錯誤:" + (ex != null ? ex.Message : ""));
                                    }
                                }


                                //UserSocket WebUser = _ws_transmit_tb[User.ID] as UserSocket;
                                //if (WebUser == null)
                                //{
                                //    SendUserState(User);
                                //    UpdateUserState(User.ID, "6"); //離線
                                //}

                                try
                                {
                                    lock (_transmit_tb.SyncRoot)
                                        _transmit_tb.Remove(obj);
                                    //線程池不會被遍歷,不鎖.
                                    _thread_tb.Remove(obj);
                                }
                                catch (Exception ex1)
                                {
                                    LogHelper.WriteLog("ThreadFunc", "從HashTable中移除用戶:" + obj.ToString() + "時發生錯誤:" + (ex1 != null ? ex1.Message : ""));
                                }
                                Thread.CurrentThread.Abort();

                                #endregion

                                break;
                            case "5":
                                #region " 群(異動)系統訊息 "

                                SendGroupSysMessage("P", clientSkt, obj.ToString(), DataGroup, DataGUID, DataBody);

                                #endregion

                                break;
                            case "6":
                                #region " 心跳包 "
                                if (_transmit_tb.ContainsKey(DataTerminal))
                                {
                                    // 直接把訊息還給發送者
                                    //Socket receiverSkt = _transmit_tb[DataTerminal] as Socket;
                                    UserSocket recUser = _transmit_tb[DataTerminal] as UserSocket;
                                    try
                                    {
                                        Socket receiverSkt = recUser.Socket;
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte(DataBody, DataType, "", "", "", DataGUID);
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        if (receiverSkt.Connected)
                                        {
                                            lock (receiverSkt)
                                            {
                                                foreach (byte[] msg in msgs)
                                                {
                                                    receiverSkt.Send(msg);
                                                    //SendData(receiverSkt, msg);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            //用戶已經斷開了
                                            LogHelper.WriteLog("ThreadFunc", "向用戶:" + DataTerminal + "轉發心跳包時發現用戶斷開連接了");
                                        }
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Info, "ThreadFunc(object obj):default", "成功向: " + _receiver + " 發送信息: " + _packetBuff);
                                    }
                                    catch (Exception ex)
                                    {
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "轉發心跳包時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadFunc", "向用戶:" + DataTerminal + "轉發心跳包時發生錯誤:" + (ex != null ? ex.Message : ""));
                                    }
                                }
                                #endregion

                                break;
                            case "7":
                                #region " 控制臺消息(7-07/7-08) "
                                ProcessConsoleCommands(DataBody);
                                #endregion

                                break;
                            case "8":
                                #region " 發送在線用戶ID清單 "

                                try
                                {
                                    DataBody = "";
                                    switch (DataGroup)
                                    {
                                        case "P":
                                            //PC
                                            lock (_transmit_tb.SyncRoot)
                                            {
                                                foreach (DictionaryEntry de in _transmit_tb)
                                                {
                                                    DataBody += de.Key.ToString() + ",";
                                                }
                                            }
                                            break;

                                        case "M":
                                            //Web + 手機
                                            lock (_ws_transmit_tb.SyncRoot)
                                            {
                                                foreach (DictionaryEntry de in _ws_transmit_tb)
                                                {
                                                    DataBody += de.Key.ToString() + ",";
                                                }
                                            }
                                            lock (_mobile_transmit_tb.SyncRoot)
                                            {
                                                foreach (DictionaryEntry de in _mobile_transmit_tb)
                                                {
                                                    DataBody += de.Key.ToString() + ",";
                                                }
                                            }
                                            break;

                                        case "A":
                                            //APP
                                            lock (_app_transmit_tb.SyncRoot)
                                            {
                                                foreach (DictionaryEntry de in _app_transmit_tb)
                                                {
                                                    DataBody += de.Key.ToString() + ",";
                                                }
                                            }
                                            break;

                                        case "F":
                                            //File
                                            lock (_file_transmit_tb.SyncRoot)
                                            {
                                                foreach (DictionaryEntry de in _file_transmit_tb)
                                                {
                                                    DataBody += de.Key.ToString() + ",";
                                                }
                                            }
                                            break;
                                        default:
                                            DataBody = "無效列表類別.";
                                            break;
                                    }


                                    // 去掉最後一個逗號
                                    if (DataBody.Length > 0)
                                    {
                                        DataBody = DataBody.Substring(0, DataBody.Length - 1);
                                    }
                                    else
                                    {
                                        DataBody = "無";
                                    }
                                    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte(DataBody, DataType, DataTerminal, DataTerminalName, "", DataGUID);

                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                    lock (clientSkt)
                                    {
                                        foreach (byte[] msg in msgs)
                                        {
                                            clientSkt.Send(msg);
                                            //SendData(clientSkt, msg);
                                        }
                                    }
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Info, "ThreadFunc(object obj):default", "成功向: " + _receiver + " 發送信息: " + _packetBuff);
                                }
                                catch (Exception ex)
                                {
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送在線用戶ID清單時:" + ex.Message);
                                    LogHelper.WriteLog("ThreadFunc", "發送在線用戶ID清單時:" + (ex != null ? ex.Message : ""));
                                }

                                #endregion

                                break;
                            case "H":
                                #region " 發送服務器健康報告 "

                                try
                                {
                                    //[#1]:120                   [PC端用戶]
                                    //[#2]:12                    [移動端用戶]
                                    //[#3]:10                    [登錄隊列]
                                    //[#4]:12/50                 [空閒登錄線程]
                                    //[#5]:10                    [APP用戶]
                                    //[#6]:2                     [文件傳送用戶]
                                    //[#7]:0                     [歷史消息標記已讀隊列]
                                    //[#8]:89                    [用戶狀態推送隊列]
                                    //[#9]:0/10                  [空間狀態推送線程]
                                    //[#10]:10                   [設備數據更新隊列]
                                    DataBody = "";

                                    //[PC端用戶]
                                    DataBody += "[#1]:" + _transmit_tb.Count.ToString() + "|";
                                    //[移動端用戶]
                                    DataBody += "[#2]:" + (_ws_transmit_tb.Count + _mobile_transmit_tb.Count).ToString() + "|";
                                    //[登錄隊列]
                                    DataBody += "[#3]:" + UsersQueue.Count.ToString() + "|";
                                    //[空閒登錄線程]
                                    DataBody += "[#4]:" + LoginThreadsQueue.Count.ToString() + "/" + MaxLoginThreads.ToString() + "|";
                                    //[APP用戶]
                                    DataBody += "[#5]:" + _app_transmit_tb.Count.ToString() + "|";
                                    //[文件傳送用戶]
                                    DataBody += "[#6]:" + _file_transmit_tb.Count.ToString() + "|";
                                    //[歷史消息標記已讀隊列]
                                    DataBody += "[#7]:" + MarkReadHistoryMsgQueue.Count.ToString() + "|";
                                    //[用戶狀態推送隊列]
                                    DataBody += "[#8]:" + StateNotifyQueue.Count.ToString() + "|";
                                    //[空間狀態推送線程]
                                    DataBody += "[#9]:" + StateNofityThreadsQueue.Count.ToString() + "/" + MaxStateNotifyThreads.ToString() + "|";
                                    //[設備數據更新隊列]
                                    DataBody += "[#10]:" + VDataQueue.Count.ToString();


                                    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte(DataBody, DataType, DataTerminal, DataTerminalName, "", DataGUID);

                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                    lock (clientSkt)
                                    {
                                        foreach (byte[] msg in msgs)
                                        {
                                            clientSkt.Send(msg);
                                            //SendData(clientSkt, msg);
                                        }
                                    }
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Info, "ThreadFunc(object obj):default", "成功向: " + _receiver + " 發送信息: " + _packetBuff);
                                }
                                catch (Exception ex)
                                {
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送在線用戶ID清單時:" + ex.Message);
                                    LogHelper.WriteLog("ThreadFunc", "發送服務器健康報告時時:" + (ex != null ? ex.Message : ""));
                                }

                                #endregion

                                break;
                            case "C":
                                #region " 群命令 "

                                // 抓出群成員
                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        // 記錄到數據庫中
                                        //DateTime MsgDT = DateTime.Now;
                                        string MsgNO = this.InsertCmd(conn, obj.ToString(), DataBody, DataGroup, DataGUID);
                                        if (MsgNO.Length > 0)
                                        {
                                            // 向管理員發的命令不轉發
                                            if (DataGroup.Length > 0)
                                            {
                                                //系統將命令轉發給群成員(以發送者的帳號) 
                                                SendGroupCommand(obj.ToString(), DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO);
                                            }
                                            // 轉發完再發回執
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送命令回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                        conn.CloseConnection();
                                    }
                                    catch
                                    {
                                        conn.CloseConnection();
                                    }
                                }

                                #endregion

                                break;
                            case "D":
                                #region " 撤回消息 "
                                //0001D發送人帳號(50b)接收對象類別(U=人;G=群)(60b)接收人/接收群(50b)GMT時間(20b)要撤回消息的GUID(32b)訊息流水號(20b)
                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        // 記錄到數據庫中(1=撤回,M=消息lrmsg)
                                        string MsgNO = this.InsertSysMsg(conn, obj.ToString(), DataBody, "1", "M", (DataTerminalName == "G" ? DataGroup : ""), (DataTerminalName == "U" ? DataGroup : ""), DataGUID);
                                        if (MsgNO.Length > 0)
                                        {
                                            //系統將訊息轉發給群成員(以發送者的帳號) 
                                            SendGroupSysBroadcast("P", "D", "1", "M", DataTerminal, DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO);
                                            // 轉發完再發回執
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "1", "M", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                        conn.CloseConnection();
                                    }
                                    catch
                                    {
                                        conn.CloseConnection();
                                    }
                                }
                                #endregion

                                break;
                            case "G":
                                #region " 群組訊息 "

                                // 抓出群成員
                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        // 記錄到數據庫中
                                        //DateTime MsgDT = DateTime.Now;
                                        string MsgNO = this.InsertMsg(conn, obj.ToString(), DataBody, DataGroup, "", "1", DataGUID, false);
                                        if (MsgNO.Length > 0)
                                        {
                                            //系統將訊息轉發給群成員(以發送者的帳號) 
                                            SendGroupBroadcast("P", obj.ToString(), DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO);

                                            // 轉發完再發回執
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                        conn.CloseConnection();
                                    }
                                    catch
                                    {
                                        conn.CloseConnection();
                                    }
                                }

                                #endregion

                                break;
                            case "I":

                                #region " 轉發屏幕截圖 "

                                //DataTerminal是接收人帳號
                                //DataTerminalName是發送人姓名
                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        // 記錄到數據庫中
                                        string MsgNO = this.InsertImage(conn, obj.ToString(), DataImage, DataGroup, DataTerminal, "1", DataGUID);
                                        if (MsgNO.Length > 0)
                                        {
                                            //沒改完,要用特殊方式打包
                                            //開始發送
                                            if (DataGroup.Length == 0)
                                            {
                                                //向人發
                                                SendP2PImage("P", obj.ToString(), DataTerminalName, DataTerminal, DataImage, conn, DataGUID, MsgNO);
                                            }
                                            else
                                            { 
                                                //向群發
                                                SendGroupImage("P", obj.ToString(), DataGroup, DataImage, DataTerminalName, conn, DataGUID, MsgNO);
                                            }
                                            // 轉發完再發回執
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                        conn.CloseConnection();
                                    }
                                    catch
                                    {
                                        conn.CloseConnection();
                                    }
                                }

                                #endregion

                                break;
                            case "U": //人對人信息
                            case "T": //測試工具使用
                                #region " 用戶訊息 "

                                //別搞暈了
                                //DataTerminal是接收人帳號
                                //DataTerminalName是發送人姓名
                                using (SQLHelper conn = new SQLHelper(DBInfo))
                                {
                                    conn.OpenConnection();
                                    try
                                    {
                                        // 記錄到數據庫中
                                        //DateTime MsgDT = DateTime.Now;
                                        //T=測試用(超哥神器)
                                        string MsgNO = this.InsertMsg(conn, obj.ToString(), DataBody, "", DataTerminal, "1", DataGUID, DataType == "T");
                                        if (MsgNO.Length > 0)
                                        {
                                            //開始發送
                                            SendP2PMessage("P", obj.ToString(), DataTerminalName, DataTerminal, DataBody, conn, DataGUID, MsgNO, DataType);

                                            // 轉發完再發回執
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                        }
                                        conn.CloseConnection();
                                    }
                                    catch
                                    {
                                        conn.CloseConnection();
                                    }
                                }

                                #endregion

                                break;

                            case "S":
                                #region " 聯絡人狀態變更 "
                                //通知在線的聯絡人當前用戶改變了狀態
                                //0=空閒|1=上線|2=離開|3=忙碌|4=不要打擾|5=隱身|6=離線|7=簽名|8=換頭像
                                User.SetUserState(DataTerminalName);
                                //特殊處理簽名操作
                                if (DataTerminalName == "7")
                                {
                                    //User.ChangeSignature = true;
                                    User.Signature = DataBody; //signature
                                    UpdateUserLog(User.ID, "2", "0", User.Signature);
                                }
                                else if (DataTerminalName == "8")
                                {
                                    // 變更頭像的處理(未完成)
                                }
                                StateNotifyQueue.Enqueue(new List<object>() { User, DataTerminalName });

                                //SendUserState(User);
                                //改為獨立線程來發
                                //如果此聯絡人在線就通知他(她)當前用戶上線了
                                //try
                                //{
                                //    Thread stateThread = new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc));
                                //    stateThread.Start(User);
                                //}
                                //catch
                                //{ }

                                //User.ChangeSignature = false; //復位
                                if (DataTerminalName != "7")
                                    UpdateUserState(User.ID, DataTerminalName); //state
                                #endregion

                                break;
                            case "P":
                                #region " 請求發送文件和同意接受文件 "
                                //發起發送文件請求: 0019P接收人帳號(50b)發起人姓名(60b)S(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                //接收人同意請求:   0019P發起人帳號(50b)接收人姓名(60b)R(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                //包體: 文件名|大小|文件完整路徑
                                //接收方同意接收的請求等到接收方T通道建立完成再轉發給發送方
                                if (DataGroup != "R" && DataGroup.Length > 0)
                                {
                                    switch (DataGroup)
                                    {
                                        case "Q":
                                            //斷開T通道的對象
                                            //0019P發起人帳號(50b)S(60b)Q(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                            //0019P接收人帳號(50b)R(60b)Q(50b)GMT時間(20b)文檔流的GUID(32b)訊息流水號(20b)
                                            string TID = DataGUID + "-" + DataTerminalName;
                                            //LogHelper.WriteLog("ThreadFunc", "準備斷開:" + TID + "的連接...");
                                            UserSocket TSocket = _file_transmit_tb[TID] as UserSocket;
                                            if (TSocket != null)
                                            {
                                                try
                                                {
                                                    if (TSocket.Socket != null)
                                                    {
                                                        if (TSocket.Socket.Connected)
                                                        {
                                                            TSocket.Socket.Shutdown(SocketShutdown.Both);
                                                            //clientSkt.Disconnect(false);
                                                        }
                                                        TSocket.Socket.Close();
                                                        //LogHelper.WriteLog("ThreadFunc", "成功斷開:" + TID + "的連接.");
                                                    }
                                                }
                                                catch (Exception ex)
                                                {
                                                    //LogHelper.WriteLog("ThreadFunc", "嘗試斷開:" + TID + "的連接時發生錯誤." + (ex != null ? ex.Message : ""));
                                                }
                                                //線程池不會被遍歷,不鎖.
                                                _file_transmit_tb.Remove(TID);
                                                //線程池不會被遍歷,不鎖.
                                                _file_thread_tb.Remove(TID);
                                            }
                                            else
                                            {
                                                LogHelper.WriteLog("ThreadFunc", "沒有找到:" + TID + ".");
                                            }
                                            break;
                                        default:
                                            string MsgNO = ProcessTransferFileRequest("P", obj.ToString(), DataType, DataTerminal, DataGroup, DataGUID, DataBody, DataTerminalName);
                                            // 向發送者發送回執7-03
                                            try
                                            {
                                                //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                                List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, MsgNO);
                                                //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                                lock (clientSkt)
                                                {
                                                    foreach (byte[] msg in msgs)
                                                    {
                                                        clientSkt.Send(msg);
                                                        //SendData(clientSkt, msg);
                                                    }
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                                LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                            }
                                            break;
                                    }
                                }
                                #endregion

                                break;

                            case "K":
                                #region " 踢人7-06 "
                                //0010K踢出目標帳號(50b)空格(60)空格(60)時間(20b)GUID(32b)訊息流水號(20b)
                                //包體:P/M (P=PC端;M=移動端)
                                //向被踢者發送回執7-06

                                UserSocket KickTarget = _transmit_tb[DataTerminal] as UserSocket;
                                if (DataBody == "M")
                                {
                                    KickTarget = _ws_transmit_tb[DataTerminal] as UserSocket;
                                    if (KickTarget == null)
                                    {
                                        KickTarget = _mobile_transmit_tb[DataTerminal] as UserSocket;
                                    }
                                }
                                if (KickTarget != null)
                                {
                                    Socket KickTargetSkt = KickTarget.Socket;
                                    bool ForceKickOut = false;
                                    try
                                    {
                                        //回執給PC端里,必須用DataGUID,因為PC端本地生成的GUID要和這個DataGUID匹配
                                        List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("06", "7", "", "", "", DataGUID, "");
                                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                        lock (KickTargetSkt)
                                        {
                                            if (KickTargetSkt.Connected)
                                            {
                                                foreach (byte[] msg in msgs)
                                                {
                                                    KickTargetSkt.Send(msg);
                                                    //SendData(KickTargetSkt, msg);
                                                }
                                            }
                                        }
                                    }
                                    catch (SocketException ex)
                                    {
                                        //客戶端異常,強踢
                                        ForceKickOut = true;
                                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                        LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                    }

                                    #region " 用戶在線就讓其自動登出,否則直接踢出 "
                                    //開踢
                                    if (ForceKickOut)
                                    {
                                        try
                                        {
                                            if (KickTargetSkt.Connected)
                                            {
                                                KickTargetSkt.Shutdown(SocketShutdown.Both);
                                                //userSkt.Disconnect(false);
                                            }
                                            KickTargetSkt.Close();
                                        }
                                        catch (SocketException ex)
                                        {
                                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                            LogHelper.WriteLog("ThreadFunc", "踢出用戶:" + DataTerminal + "時出錯:" + (ex != null ? ex.Message : ""));
                                        }

                                        #region " 聯絡人狀態變更 "
                                        ProcessPCUserState(KickTarget);
                                        #endregion

                                        try
                                        {
                                            lock (_transmit_tb.SyncRoot)
                                                _transmit_tb.Remove(DataTerminal);
                                            Thread kickTargetThread = _thread_tb[DataTerminal] as Thread;
                                            if (kickTargetThread != null)
                                            {
                                                kickTargetThread.Abort();
                                                _thread_tb.Remove(DataTerminal);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                            LogHelper.WriteLog("ThreadFunc", "結束被踢出用戶:" + DataTerminal + "線程時出錯:" + (ex != null ? ex.Message : ""));
                                        }
                                    }
                                    #endregion
                                }
                                else
                                {
                                    //Kick FileTransferID
                                    KickTarget = _file_transmit_tb[DataTerminal] as UserSocket;
                                    if (KickTarget != null)
                                    {
                                        Socket KickTargetSkt = KickTarget.Socket;
                                        try
                                        {
                                            if (KickTargetSkt.Connected)
                                            {
                                                KickTargetSkt.Shutdown(SocketShutdown.Both);
                                                //userSkt.Disconnect(false);
                                            }
                                            KickTargetSkt.Close();
                                        }
                                        catch (SocketException ex)
                                        {
                                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                            LogHelper.WriteLog("ThreadFunc", "踢出用戶:" + DataTerminal + "時出錯:" + (ex != null ? ex.Message : ""));
                                        }

                                        try
                                        {
                                            lock (_file_transmit_tb.SyncRoot)
                                                _file_transmit_tb.Remove(DataTerminal);
                                            Thread kickTargetThread = _file_thread_tb[DataTerminal] as Thread;
                                            if (kickTargetThread != null)
                                            {
                                                kickTargetThread.Abort();
                                                _file_thread_tb.Remove(DataTerminal);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                            LogHelper.WriteLog("ThreadFunc", "結束被踢出用戶:" + DataTerminal + "線程時出錯:" + (ex != null ? ex.Message : ""));
                                        }
                                    }
                                }

                                try
                                {
                                    //通知管理員執行成功7-03
                                    List<byte[]> msgs = ConvertMethod.ConvertMsgToByte("03", "7", "", "", "", DataGUID, "");
                                    //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                    lock (clientSkt)
                                    {
                                        if (clientSkt.Connected)
                                        {
                                            foreach (byte[] msg in msgs)
                                            {
                                                clientSkt.Send(msg);
                                                //SendData(clientSkt, msg);
                                            }
                                        }
                                    }
                                }
                                catch (SocketException ex)
                                {
                                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                                    LogHelper.WriteLog("ThreadFunc", "發送消息回執時:" + (ex != null ? ex.Message : ""));
                                }
                                #endregion

                                break;
                        }
                    }
                    catch (SocketException)
                    {
                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):catch (SocketException)", "用戶:" + obj.ToString() + "異常斷開連接.");
                        try
                        {
                            LogHelper.WriteLog("ThreadFunc", "用戶:" + obj.ToString() + "異常斷開連接.");
                            if (clientSkt.Connected)
                            {
                                clientSkt.Shutdown(SocketShutdown.Both);
                                //clientSkt.Disconnect(false);
                            }
                            clientSkt.Close();

                            #region " 聯絡人狀態變更 "
                            //通知在線的聯絡人當前用戶改變了狀態
                            //User.SetUserState("6");
                            //UpdateUserLog(User.ID, "1", "0", "PC端異常登出");
                            //如果手機端沒在線就通知聯絡人我離線了
                            ProcessPCUserState(User);
                            //UserSocket WebUser = _ws_transmit_tb[User.ID] as UserSocket;
                            //if (WebUser == null)
                            //{
                            //    SendUserState(User);
                            //    UpdateUserState(User.ID, "6"); //離線
                            //}
                            #endregion

                            lock (_transmit_tb.SyncRoot)
                                _transmit_tb.Remove(obj);
                            //線程池不會被遍歷,不鎖.
                            _thread_tb.Remove(obj);
                        }
                        catch
                        { }
                        Thread.CurrentThread.Abort();
                    }
                }
            }
        }
Example #15
0
 protected void SendVoice(string DataTerminal, string DataGroup, byte[] DataVoice, string DataTerminalName, string DataGUID, string VoiceSeconds)
 {
     //處理邏輯: 將lrtdmsg.msg_img留空. 再將完整音頻數據放到對照表lrmsgimg里.
     //          用戶點擊錄音圖標再下載完整音頻數據
     //          
     try
     {
         string curUserID = m_userToken.BindingUser.ID;
         //DataTerminal是接收人帳號
         //DataTerminalName是發送人姓名
         using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
         {
             conn.OpenConnection();
             try
             {
                 // 記錄到數據庫中
                 string MsgNO = InsertVoice(conn, curUserID, DataVoice, DataGroup, DataTerminal, "1", DataGUID, VoiceSeconds);
                 if (MsgNO.Length > 0)
                 {
                     //沒改完,要用特殊方式打包
                     //開始發送
                     if (DataGroup.Length == 0)
                     {
                         //向人發
                         SendP2PVoice(curUserID, DataTerminalName, DataTerminal, conn, DataGUID, MsgNO, VoiceSeconds);
                     }
                     else
                     {
                         //向群發
                         SendGroupVoice(DataTerminal, DataGroup, DataTerminalName, conn, DataGUID, MsgNO, VoiceSeconds);
                     }
                     // 轉發完再發回執
                     // 向發送者發送回執7-03
                     PushFeedback(DataGUID, MsgNO);
                 }
                 conn.CloseConnection();
             }
             catch
             {
                 conn.CloseConnection();
             }
         }
     }
     catch (Exception ex)
     {
         LogHelper.WriteLog("SendVoice", ex.Message);
     }
 }
Example #16
0
        /// <summary>
        /// 系統公告消息
        /// </summary>
        /// <param name="Command"></param>
        /// <param name="Seq"></param>
        /// <param name="Region"></param>
        /// <param name="MsgText"></param>
        protected void SendSysNotice(string Command, string Seq, string Region, string MsgText)
        {

            #region " 更新公告內容和區域 "

            lock (m_asyncSocketServer.SysNotices.SyncRoot)
            {
                if (m_asyncSocketServer.SysNotices.ContainsKey(Region))
                {
                    //ALL 也會存里面
                    List<NoticeMsg> nMsgs = (List<NoticeMsg>)m_asyncSocketServer.SysNotices[Region];
                    NoticeMsg nMsg = nMsgs.Find(delegate(NoticeMsg _msg) { return _msg.MsgSeq == Seq; });
                    if (nMsg != null)
                    {
                        if (Command == "1")
                        {
                            // 替換現有的公告
                            nMsg.MsgText = MsgText;
                        }
                        else
                        {
                            // 移除現有的公告
                            nMsgs.Remove(nMsg);
                            if (nMsgs.Count == 0)
                            {
                                // 當前區域沒有公告了,將區域移除
                                m_asyncSocketServer.SysNotices.Remove(Region);
                            }
                        }
                    }
                    else
                    {
                        if (Command == "1")
                        {
                            // 新公告
                            nMsgs.Add(new NoticeMsg() { MsgSeq = Seq, MsgText = MsgText });
                        }
                    }
                }
                else
                {
                    if (Command == "1")
                    {
                        //新公告
                        m_asyncSocketServer.SysNotices.Add(Region, new List<NoticeMsg>() { new NoticeMsg() { MsgSeq = Seq, MsgText = MsgText } });
                    }
                }
            }

            #endregion

            // 抓出群成員
            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
            {
                conn.OpenConnection();
                try
                {
                    #region " 更新廣播內容到數據庫 "

                    if (conn.OpenDataTable("select uid from lrbroadcast (nolock) where region_id = '" + Region + "' and bdc_seq = '" + Seq + "'", CommandType.Text).Rows.Count > 0)
                    {
                        //有資料
                        conn.ExecuteSQL("update a set a.bdc_cmd='" + Command + "',a.bdc_text=N'" + MsgText + "' from lrbroadcast a where a.region_id = '" + Region + "' and a.bdc_seq = '" + Seq + "'");
                    }
                    else
                    {
                        //沒資料
                        if (Command == "1")
                        {
                            conn.ExecuteSQL("insert into lrbroadcast (region_id,bdc_seq,bdc_text,bdc_cmd) values('" + Region + "','" + Seq + "',N'" + MsgText + "','" + Command + "')");
                        }
                    }

                    #endregion

                    string strWhere = "where ie_cancel <> 'Y' and user_state <> '6'";
                    if (Region.ToUpper() == "ALL")
                    {
                        strWhere += " and user_region > ''";
                    }
                    else
                    {
                        strWhere += " and user_region = '" + Region + "'";
                    }
                    DataTable UserList = conn.OpenDataTable("select user_no from lrtduser (nolock) " + strWhere, CommandType.Text);
                    //儘早釋放SQL資源
                    conn.CloseConnection();

                    if (UserList.Rows.Count > 0)
                    {
                        // 提前打包好,沒必要放到for循環里去做
                        List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(MsgText, "B", Command, Seq, Region, "", "");

                        foreach (DataRow User in UserList.Rows)
                        {
                            //有沒有必要PC和MOBLIE端各開個一個欄位來存放消息是否讀取的標記?

                            #region " PC Client "

                            PushMessage("", msgs, User["user_no"].ToString(), m_asyncSocketServer.PcUserTokenList, "SendSysNotice");

                            #endregion

                            #region " Mobile Client "

                            //Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.MobileUserTokenList, "SendGroupSysMessage");

                            #endregion

                        }
                    }
                    UserList.Dispose();
                    UserList = null;

                    #region " 向發送者發送回執7-03 "

                    PushFeedback("", "");

                    #endregion
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
        }
Example #17
0
        private void GetSysData()
        {
            //1.活動用戶(14天內有發消息的)
            //2.在線用戶
            //3.註冊用戶
            //4.今天消息量
            //5.累積消息量
            string ActiveDate = DateTime.Now.AddDays(-14).ToString("yyyy/MM/dd"); // 兩周內
            string SQL = "";
            //抓數據
            using (SQLHelper conn = new SQLHelper(DBInfo))
            {
                try
                {
                    conn.OpenConnection();

                    //1.活動用戶(14天內有發消息的)
                    SQL = "select COUNT(1) as active_users_count from " + "\r\n" +
                          "( " + "\r\n" +
                          "   select a.msg_from from lrtdmsg a (nolock) join lrtduser b (nolock) on a.msg_from=b.user_no where a.msg_date>='" + ActiveDate + "' group by a.msg_from " + "\r\n" +
                          ") a";
                    ActiveUsersCount = conn.OpenDataTable(SQL, CommandType.Text).Rows[0]["active_users_count"].ToString();

                    //2.在線用戶(App客戶端不算)
                    OnlineUsersCount = ((PcUserTokenList != null ? PcUserTokenList.Count : 0) + (MobileUserTokenList != null ? MobileUserTokenList.Count : 0)).ToString();

                    //3.註冊用戶
                    SQL = "select COUNT(1) as registered_users_count from lrtduser (nolock)";
                    RegisteredUsersCount = conn.OpenDataTable(SQL, CommandType.Text).Rows[0]["registered_users_count"].ToString();

                    //4.今天消息量
                    SQL = "select COUNT(1) as today_msgs_count from lrtdmsg (nolock) where msg_date='" + DateTime.Now.ToString("yyyy/MM/dd") + "' and msg_from in (select user_no from lrtduser (nolock))";
                    TodayMessagesCount = conn.OpenDataTable(SQL, CommandType.Text).Rows[0]["today_msgs_count"].ToString();

                    //5.累積消息量
                    SQL = "select COUNT(1) as total_msgs_count from lrtdmsg (nolock) where msg_from in (select user_no from lrtduser (nolock))";
                    TotalMessagesCount = conn.OpenDataTable(SQL, CommandType.Text).Rows[0]["total_msgs_count"].ToString();

                    conn.CloseConnection();
                }
                catch (Exception ex)
                {
                    conn.CloseConnection();
                    //clsClientLog.WriteLog(clsClientLog.LogType.Error, "SysTreadFunc", "讀取平臺數據時:" + (ex != null ? ex.Message : ""));
                    LogHelper.WriteLog("SysTreadFunc()", "讀取平臺數據時:" + (ex != null ? ex.Message : ""));
                    return;
                }
            }
        }
Example #18
0
        /// <summary>
        /// 保存登錄流量和耗時數據
        /// </summary>
        /// <param name="userToken"></param>
        /// <param name="DataTerminal"></param>
        /// <param name="DataBody"></param>
        protected void SaveLoginStatData(SocketUserToken userToken, string DataTerminal, string DataBody)
        {
            //DataBody包體格式:
            //類別A;流量(Byte);耗時(ms);開始(當地)日期(yyyy/MM/dd);開始(當地)時間(HH:mm:ss.fff);結束(當地)日期(yyyy/MM/dd);結束(當地)時間(HH:mm:ss.fff)|類別B;流量(Byte);耗時(ms);開始(當地)日期(yyyy/MM/dd);開始(當地)時間(HH:mm:ss.fff);結束(當地)日期(yyyy/MM/dd);結束(當地)時間(HH:mm:ss.fff)
            //邏輯:
            //根據帳號+IP抓到lrlxlog里此用戶最大UID作業log_uid
            string[] StatData = DataBody.Split('|');
            if (StatData.Length > 0)
            {
                DateTime curDate = DateTime.Now;
                string Today = curDate.ToString("yyyy/MM/dd");
                string Yesterday = curDate.AddDays(-1).ToString("yyyy/MM/dd"); //防止登錄時剛好跨天
                using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                {
                    conn.OpenConnection();
                    try
                    {
                        conn._Transaction = conn._Connection.BeginTransaction();

                        DataTable recTmp = conn.OpenDataTable("select MAX(uid) as log_uid from lrlxlog (nolock) " + "\r\n" +
                                                              "where log_date between '" + Yesterday + "' and '" + Today + "' and user_no='" + DataTerminal + "' and log_ip='" + ((IPEndPoint)userToken.ConnectSocket.RemoteEndPoint).Address.ToString() + "'", CommandType.Text);
                        if (recTmp.Rows.Count > 0)
                        {
                            long log_uid = long.Parse(recTmp.Rows[0]["log_uid"].ToString());
                            string[] statValues;
                            foreach (string stat in StatData)
                            {
                                statValues = stat.Split(';');
                                //[0]:類別
                                //[1]:流量(Byte)
                                //[2]:耗時(ms)
                                //[3]:開始(當地)日期(yyyy/MM/dd)
                                //[4]:開始(當地)時間(HH:mm:ss.fff)
                                //[5]:結束(當地)日期(yyyy/MM/dd)
                                //[6]:結束(當地)時間(HH:mm:ss.fff)
                                if (statValues.Length == 7)
                                {
                                    conn.ExecuteSQL("insert into lrlxstat (log_uid,stat_type,data_size,duration_time,stat_sdate,stat_stime,stat_edate,stat_etime,ie_ymd,ie_time,ie_user)" + "\r\n" +
                                                    "values(" + log_uid + ",'" + statValues[0] + "'," + statValues[1] + "," + statValues[2] + ",'" + statValues[3] + "','" + statValues[4] + "','" + statValues[5] + "','" + statValues[6] + "','" + curDate.ToString("yyyy/MM/dd") + "','" + curDate.ToString("HH:mm:ss") + "','" + DataTerminal + "')");
                                }
                            }
                        }
                        conn._Transaction.Commit();
                        conn.CloseConnection();
                    }
                    catch
                    {
                        conn._Transaction.Rollback();
                        conn.CloseConnection();
                    }
                }
            }
        }
Example #19
0
        /// <summary>
        /// 處理當前用戶離線狀態的通知
        /// </summary>
        /// <param name="userToken"></param>
        private void ProcessUserOfflineState(SocketUserToken userToken)
        {
            if (userToken == null || userToken.BindingUser == null)
                return;
            User curUser = userToken.BindingUser;

            try
            {
                //判斷用戶有沒登錄成功,有就通知聯絡人用戶狀態變更q
                if (m_pcUserTokenList.ContainsKey(curUser.ID))
                {
                    //目前只寫對PC端用戶,應該還要考慮其他用戶
                    //通知在線的聯絡人當前用戶改變了狀態
                    curUser.SetUserState("6");
                    using (SQLHelper conn = new SQLHelper(DBInfo))
                    {
                        conn.OpenConnection();
                        try
                        {
                            DoUpdateUserLog(conn, curUser.ID, "1", ((int)curUser.Mobile).ToString(), "客戶端登出", ((IPEndPoint)userToken.ConnectSocket.RemoteEndPoint).Address.ToString(), "", "", null);
                            //如果手機端沒在線就通知聯絡人此人離線了
                            SocketUserToken MobileUser = m_mobileUserTokenList[curUser.ID] as SocketUserToken;
                            if (MobileUser == null)
                            {
                                //StateNotifyQueue.Enqueue(new List<object>() { userToken, ((int)curUser.State).ToString() });
                                //ID,狀態,簽名,聯絡人清單,頭像數據
                                if (curUser.Contacts.Count > 0)
                                    StateNotifyQueue.Enqueue(new List<object>() { curUser.ID, ((int)curUser.State).ToString(), curUser.Signature, curUser.Contacts, null });

                                DoUpdateUserState(conn, curUser.ID, "6"); //離線
                            }
                            conn.CloseConnection();
                        }
                        catch
                        {
                            conn.CloseConnection();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("ProcessUserOfflineState", "通知聯絡人用戶:" + curUser.ID + "離線時出錯:" + (ex != null ? ex.Message : ""));
            }

            ////通知在線的聯絡人當前用戶改變了狀態
            //curUser.SetUserState("6");
            //using (SQLHelper conn = new SQLHelper(DBInfo))
            //{
            //    conn.OpenConnection();
            //    try
            //    {
            //        DoUpdateUserLog(conn, curUser.ID, "1", "0", "PC端登出");
            //        //如果手機端沒在線就通知聯絡人此人離線了
            //        UserSocket WebUser = _ws_transmit_tb[curUser.ID] as UserSocket;
            //        if (WebUser == null)
            //        {
            //            WebUser = _mobile_transmit_tb[curUser.ID] as UserSocket;
            //            if (WebUser == null)
            //            {
            //                StateNotifyQueue.Enqueue(new List<object>() { curUser, ((int)curUser.State).ToString() });
            //                DoUpdateUserState(conn, curUser.ID, "6"); //離線
            //            }
            //        }
            //        conn.CloseConnection();
            //    }
            //    catch
            //    {
            //        conn.CloseConnection();
            //    }
            //}
        }
Example #20
0
        /// <summary>
        /// 轉發群消息
        /// </summary>
        /// <param name="DataTerminal"></param>
        /// <param name="DataGroup"></param>
        /// <param name="DataGUID"></param>
        /// <param name="DataBody"></param>
        /// <param name="DataTerminalName"></param>
        /// <param name="conn"></param>
        /// <param name="MsgNO"></param>
        protected void SendGroupBroadcast(string DataTerminal, string DataGroup, string DataBody, string DataTerminalName, string MsgGUID, bool IsPushMode)
        {
            // 抓出群成員
            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
            {
                conn.OpenConnection();
                try
                {
                    // 記錄到數據庫中
                    // DataType == "L"時, DataTerminalName為Pull消息子分類(表名)
                    string MsgNO = this.InsertMsg(conn, DataTerminal, DataBody, DataGroup, "", "1", (IsPushMode ? "" : DataTerminalName), MsgGUID, false, IsPushMode);
                    if (MsgNO.Length > 0)
                    {
                        // 系統將訊息轉發給群成員(以發送者的帳號) 
                        //base.SendGroupBroadcast(DataTerminal, DataGroup, DataBody, DataTerminalName, conn, DataGUID, MsgNO, DataType == "G");
                        if (IsPushMode)
                        {
                            DataTable UserList = conn.OpenDataTable("select a.msg_to from lrmsgstate a (nolock) where a.msg_no=" + MsgNO + " and a.msg_state='0'", CommandType.Text);
                            if (UserList.Rows.Count > 0)
                            {
                                string Users = "";
                                //系統將訊息轉發給群成員(以發送者的帳號) 
                                //問題: 1.只有帳號沒有姓名.Client無法顯示姓名
                                //      2.沒有發送日期和時間
                                // PC 和 Mobile 要用到的信息.提前打包好,沒必要放到for循環里去做
                                List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(DataBody, "4", DataTerminal, DataTerminalName, DataGroup, MsgGUID, MsgNO);
                                // Web 要用到的信息.提前打包好,沒必要放到for循環里去做 - 暫時不實現
                                //byte[] msgw = WebConvertMethod.ConvertMsgToByte(DataBody, "4", DataTerminal, DataTerminalName, DataGroup, MsgNO);

                                foreach (DataRow User in UserList.Rows)
                                {
                                    #region " PC Client "

                                    Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.PcUserTokenList, "SendGroupBroadcast");

                                    #endregion

                                    #region " Mobile Client "

                                    Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.MobileUserTokenList, "SendGroupBroadcast");

                                    #endregion

                                    #region " Web Client "

                                    //recUser = _ws_transmit_tb[User["msg_to"].ToString()] as UserSocket;
                                    //if (recUser != null)
                                    //{
                                    //    userSkt = recUser.Socket;
                                    //    //放到for循環外面去,提高效率
                                    //    //byte[] msg = WebConvertMethod.ConvertMsgToByte(DataBody, "4", DataTerminal, DataTerminalName, DataGroup, MsgNO);
                                    //    try
                                    //    {
                                    //        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                                    //        lock (userSkt)
                                    //        {
                                    //            userSkt.Send(msgw);
                                    //            //SendData(userSkt, msg);
                                    //        }
                                    //        Users += "'" + User["msg_to"].ToString() + "',";
                                    //    }
                                    //    catch (SocketException ex)
                                    //    {
                                    //        //掉線了,直接干掉.
                                    //        try
                                    //        {
                                    //            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):catch (SocketException)", "轉發群消息給用戶:" + User["msg_to"].ToString() + "時發生異常,斷開連接.");
                                    //            LogHelper.WriteLog("SendGroupBroadcast", "轉發群消息給手機用戶:" + User["msg_to"].ToString() + "時發生異常,斷開連接." + (ex != null ? ex.Message : ""));
                                    //            try
                                    //            {
                                    //                if (userSkt.Connected)
                                    //                {
                                    //                    userSkt.Shutdown(SocketShutdown.Both);
                                    //                    //userSkt.Disconnect(false);
                                    //                }
                                    //                userSkt.Close();

                                    //                #region " 聯絡人狀態變更 "
                                    //                //通知在線的聯絡人當前用戶改變了狀態
                                    //                //recUser.SetUserState("6");
                                    //                //UpdateUserLog(recUser.ID, "1", "1", "Mobile端異常登出");
                                    //                //如果PC端沒在線就通知聯絡人此人離線了
                                    //                ProcessWebUserState(recUser);
                                    //                //UserSocket PCUser = _transmit_tb[recUser.ID] as UserSocket;
                                    //                //if (PCUser == null)
                                    //                //{
                                    //                //    SendUserState(recUser);
                                    //                //    UpdateUserState(recUser.ID, "6"); //離線
                                    //                //}
                                    //                #endregion

                                    //                lock (_ws_transmit_tb.SyncRoot)
                                    //                    _ws_transmit_tb.Remove(User["msg_to"].ToString());
                                    //                Thread userThread = _ws_thread_tb[User["msg_to"].ToString()] as Thread;
                                    //                userThread.Abort();
                                    //                //線程池不會被遍歷,不鎖.
                                    //                _ws_thread_tb.Remove(User["msg_to"].ToString());
                                    //            }
                                    //            catch
                                    //            { }
                                    //        }
                                    //        catch
                                    //        { }
                                    //    }
                                    //}
                                    #endregion
                                }
                                // 去掉最後一個逗號
                                if (Users.Length > 0)
                                {
                                    Users = Users.Substring(0, Users.Length - 1);
                                    // 標記為已讀                    
                                    DateTime now = DateTime.Now;
                                    string ymd = now.ToString("yyyy/MM/dd");
                                    string time = now.ToString("HH:mm:ss");
                                    conn.ExecuteSQL("update a set a.msg_state='1',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lrmsgstate a where a.msg_no=" + MsgNO + " and a.msg_state='0' and a.msg_to in (" + Users + ")");
                                }
                            }
                            UserList.Dispose();
                            UserList = null;
                        }

                        //處理同一帳號多個端登錄的轉發.
                        if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.PC ||
                            m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                        {
                            //來自PC端消息.
                            //檢查相同帳號Mobile(Web)端有沒有登錄,有就轉發一次.
                            #region " Web Client "

                            //recUser = _ws_transmit_tb[DataTerminal] as UserSocket;
                            //if (recUser != null)
                            //{
                            //    userSkt = recUser.Socket;
                            //    // 系統將訊息轉發給群成員(以發送者的帳號) 
                            //    //問題: 1.只有帳號沒有姓名.Client無法顯示姓名
                            //    //      2.沒有發送日期和時間
                            //    byte[] msg = WebConvertMethod.ConvertMsgToByte(DataBody, "4", "", "", DataGroup, MsgNO);
                            //    try
                            //    {
                            //        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                            //        lock (userSkt)
                            //        {
                            //            userSkt.Send(msg);
                            //            //SendData(userSkt, msg);
                            //        }
                            //    }
                            //    catch (SocketException ex)
                            //    {
                            //        //掉線了,直接干掉.
                            //        try
                            //        {
                            //            LogHelper.WriteLog("SendGroupBroadcast", "轉發群消息給手機用戶:" + DataTerminal + "時發生異常,斷開連接." + (ex != null ? ex.Message : ""));
                            //            //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):catch (SocketException)", "轉發群消息給Mobile端用戶:" + DataTerminal + "時發生異常,斷開連接.");
                            //            if (userSkt.Connected)
                            //            {
                            //                userSkt.Shutdown(SocketShutdown.Both);
                            //                //userSkt.Disconnect(false);
                            //            }
                            //            userSkt.Close();

                            //            #region " 聯絡人狀態變更 "
                            //            //通知在線的聯絡人當前用戶改變了狀態
                            //            //recUser.SetUserState("6");
                            //            //UpdateUserLog(recUser.ID, "1", "1", "Mobile端異常登出");
                            //            //如果PC端沒在線就通知聯絡人此人離線了
                            //            ProcessWebUserState(recUser);
                            //            //UserSocket PCUser = _transmit_tb[recUser.ID] as UserSocket;
                            //            //if (PCUser == null)
                            //            //{
                            //            //    SendUserState(recUser);
                            //            //    UpdateUserState(recUser.ID, "6"); //離線
                            //            //}
                            //            #endregion

                            //            lock (_ws_transmit_tb.SyncRoot)
                            //                _ws_transmit_tb.Remove(DataTerminal);
                            //            Thread userThread = _ws_thread_tb[DataTerminal] as Thread;
                            //            userThread.Abort();
                            //            //線程池不會被遍歷,不鎖.
                            //            _ws_thread_tb.Remove(DataTerminal);
                            //        }
                            //        catch
                            //        { }
                            //    }
                            //}
                            #endregion

                            #region " Mobile Client "

                            PushRoaming(DataTerminal, ParseProtocol.ConvertMsgToByte(DataBody, "4", "", "", DataGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.MobileUserTokenList);

                            #endregion
                        }
                        if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.Mobile ||
                            m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                        {
                            //來自Mobile(Web)端消息.
                            //檢查相同帳號Web端有沒有登錄,有就轉發一次.
                            #region " PC Client "

                            PushRoaming(DataTerminal, ParseProtocol.ConvertMsgToByte(DataBody, "4", "", "", DataGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList);

                            #endregion
                        }

                        // 轉發完再發回執
                        // 向發送者發送回執7-03
                        this.PushFeedback(MsgGUID, MsgNO);
                    }
                    conn.CloseConnection();
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
        }
Example #21
0
 /// <summary>
 /// 一次性設置用戶狀態
 /// </summary>
 /// <param name="UserID"></param>
 /// <param name="conn"></param>
 /// <param name="State"></param>
 private void UpdateUsersState(string State)
 {
     using (SQLHelper conn = new SQLHelper(DBInfo))
     {
         conn.OpenConnection();
         try
         {
             conn.ExecuteSQL("update a set a.user_state='" + State + "' from lrtduser a");
             conn.CloseConnection();
         }
         catch
         {
             conn.CloseConnection();
         }
     }
 }
Example #22
0
        /// <summary>
        /// 轉發用戶命令到訂閱號
        /// </summary>
        /// <param name="DataTerminal"></param>
        /// <param name="DataGroup"></param>
        /// <param name="DataGUID"></param>
        /// <param name="DataBody"></param>
        /// <param name="DataTerminalName"></param>
        /// <param name="conn"></param>
        /// <param name="MsgNO"></param>
        protected void SendRequestToSubService(string DataTerminal, string DataGroup, string DataBody, string DataTerminalName, string MsgGUID, bool SaveMSG)
        {
            string MsgNO = "";
            // 抓出群成員
            if (SaveMSG)
            {
                // 只有真正來自用戶的請求才會被記錄到數據庫中.
                // 由後臺模擬用戶請求則不記錄到數據庫,也不會進行用戶多端設備漫遊
                using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                {
                    conn.OpenConnection();
                    try
                    {
                        // 記錄到數據庫中
                        // DataType == "L"時, DataTerminalName為Pull消息子分類(表名)
                        MsgNO = this.InsertMsg(conn, DataTerminal, DataBody, DataGroup, "", "1", MsgGUID, false, false);
                        if (MsgNO.Length > 0)
                        {
                            //處理同一帳號多個端登錄的轉發.
                            if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.PC ||
                                m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                            {
                                //來自PC端消息.
                                //檢查相同帳號Mobile(Web)端有沒有登錄,有就轉發一次.
                                #region " Mobile Client "

                                PushRoaming(DataTerminal, ParseProtocol.ConvertMsgToByte(DataBody, "4", "", "", DataGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.MobileUserTokenList);

                                #endregion
                            }
                            if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.Mobile ||
                                m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                            {
                                //來自Mobile(Web)端消息.
                                //檢查相同帳號Web端有沒有登錄,有就轉發一次.
                                #region " PC Client "

                                PushRoaming(DataTerminal, ParseProtocol.ConvertMsgToByte(DataBody, "4", "", "", DataGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList);

                                #endregion
                            }
                        }
                        conn.CloseConnection();
                    }
                    catch
                    {
                        conn.CloseConnection();
                    }
                }
            }
            else
            {
                MsgNO = "n/a";
            }
            try
            {
                //用戶向訂閱號發命令
                if (m_asyncSocketServer.SubServiceTokenList.ContainsKey("#" + DataGroup + "#"))
                {
                    #region " 訂閱號在運行中則繼續作業 "

                    try
                    {
                        SocketUserToken SubSrvToken = m_asyncSocketServer.SubServiceTokenList["#" + DataGroup + "#"];
                        Socket subSrvSkt = SubSrvToken.ConnectSocket;
                        List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(DataBody, "W", DataTerminal, DataTerminalName, DataGroup, "N/A", "-1");
                        //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息
                        if (subSrvSkt.Connected)
                        {
                            lock (subSrvSkt)
                            {
                                foreach (byte[] msg in msgs)
                                {
                                    SubSrvToken.AsyncSendAgent.DoSendBuffer(msg);
                                }
                            }
                        }
                    }
                    catch (SocketException ex)
                    {
                        //clsClientLog.WriteLog(clsClientLog.LogType.Error, "ThreadFunc(object obj):default", "發送消息回執時:" + ex.Message);
                        LogHelper.WriteLog("SendRequestToSubService", "發送7-09消息回執時:" + (ex != null ? ex.Message : ""));

                        //7-09:訂閱號已經停止工作
                        PushSubSrvFeedback(DataGroup);
                    }

                    #endregion
                }
                else
                {
                    #region " 訂閱號未運行,向用戶返回信息"

                    //7-09:訂閱號已經停止工作
                    //PushSubSrvFeedback(DataGroup);
                    SendSubServiceFeedbackToUser(DataTerminal, DataGroup, "訂閱號已經停止工作\r\nSubscription service is not available.", Guid.NewGuid().ToString().Replace("-", "").ToUpper());

                    #endregion
                }

                // 轉發完再發回執
                // 向發送者發送回執7-03
                this.PushFeedback(MsgGUID, MsgNO);
            }
            catch
            { }
        }
Example #23
0
        public void Start(IPEndPoint localEndPoint)
        {
            listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            listenSocket.Bind(localEndPoint);
            listenSocket.Listen(m_maxServerLoading);

            //LogHelper.WriteLog("Start", "服務器已啟動,正在監聽...");
            LogHelper.WriteLog("Start", string.Format("服務器已啟動,正在監聽IP: {0} 端口號: {1}", localEndPoint.Address.ToString(), localEndPoint.Port.ToString()));

            //測試時如果數據庫為正式區,這句不能執行.
            UpdateUsersState("6"); //全部離線
            //測試時如果數據庫為正式區,這句不能執行.

            #region " 檢查lrtdseq是否添加 并 生成系統廣播"

            try
            {
                using (SQLHelper conn = new SQLHelper(DBInfo))
                {
                    conn.OpenConnection();
                    try
                    {
                        //DataTable test = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '1',@seqNO output select @seqNO", CommandType.Text);
                        //if (test.Rows.Count > 0)
                        //{

                        //}
                        DataTable dtSeq = conn.OpenDataTable("select seq_no from lrtdseq (nolock) where seq_type='1'", CommandType.Text);
                        if (dtSeq.Rows.Count > 0)
                        {
                            //    SeqNO = long.Parse(dtSeq.Rows[0]["seq_no"].ToString());
                            //    clsClientLog.WriteLog(clsClientLog.LogType.System, hostName, "消息起始ID: " + SeqNO.ToString());
                        }
                        else
                        {
                            conn.ExecuteSQL("insert into lrtdseq (seq_type,seq_no) values('1',0)");
                            //clsClientLog.WriteLog(clsClientLog.LogType.System, hostName, "消息起始ID: 0");
                            LogHelper.WriteLog("WebThreadFunc", "正式區消息起始ID:0");
                        }
                        ////For Test
                        //dtSeq = conn.OpenDataTable("select seq_no from lrtdseq (nolock) where seq_type='2'", CommandType.Text);
                        //if (dtSeq.Rows.Count > 0)
                        //{
                        //    //    SeqNO = long.Parse(dtSeq.Rows[0]["seq_no"].ToString());
                        //    //    clsClientLog.WriteLog(clsClientLog.LogType.System, hostName, "消息起始ID: " + SeqNO.ToString());
                        //}
                        //else
                        //{
                        //    conn.ExecuteSQL("insert into lrtdseq (seq_type,seq_no) values('2',0)");
                        //    //clsClientLog.WriteLog(clsClientLog.LogType.System, hostName, "消息起始ID: 0");
                        //    LogHelper.WriteLog("WebThreadFunc", "測試區消息起始ID:0");
                        //}

                        // 生成系統公告
                        dtSeq = conn.OpenDataTable("select * from lrbroadcast (nolock) where bdc_cmd = '1' order by region_id,bdc_seq", CommandType.Text);
                        if (dtSeq.Rows.Count > 0)
                        {
                            DataTable dtRegions = dtSeq.DefaultView.ToTable(true, "region_id");
                            foreach (DataRow drRegion in dtRegions.Rows)
                            {
                                DataRow[] dtRows = dtSeq.Select("region_id = '" + drRegion["region_id"].ToString() + "'", "bdc_seq");
                                if (dtRows.Length > 0)
                                {
                                    List<NoticeMsg> nMsgs = new List<NoticeMsg>();
                                    foreach (DataRow dr in dtRows)
                                    {
                                        nMsgs.Add(new NoticeMsg() { MsgSeq = dr["bdc_seq"].ToString(), MsgText = dr["bdc_text"].ToString() });
                                    }
                                    this.SysNotices.Add(drRegion["region_id"].ToString(), nMsgs);
                                }
                            }
                            dtRegions.Dispose();
                            dtRegions = null;
                        }

                        dtSeq.Dispose();
                        dtSeq = null;
                        conn.CloseConnection();
                    }
                    catch
                    {
                        conn.CloseConnection();
                    }
                }
            }
            catch (Exception ex)
            {
                //clsClientLog.WriteLog(clsClientLog.LogType.System, hostName, "獲得消息起始ID失敗.原因: " + ex.Message);
                LogHelper.WriteLog("WebThreadFunc", "獲得消息起始ID失敗.原因:" + (ex != null ? ex.Message : ""));
                return;
            }

            #endregion

            #region " 開一個獨立的線程來定時發送1.活動用戶數,2.在線用戶數,3註冊用戶數,4.今日消息數,5.累積消息數 "

            SysThread = new Thread(SysTreadFunc);
            SysThread.Start();

            #endregion

            // 開一個線程來標記歷史消息為已讀 
            MarkReadThread = new Thread(MarkReadThreadFunc);
            MarkReadThread.Start();

            // 開一個線程來推送用戶在線狀態 
            // 初始化-MaxStateNotifyThreads
            for (int i = 0; i < MaxStateNotifyThreads; i++)
            {
                StateNofityThreadsQueue.Enqueue(new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc)));
            }
            StateNotifyControlThread = new Thread(StateNotifyControlThreadFunc);
            StateNotifyControlThread.Priority = ThreadPriority.AboveNormal; // 次高級
            StateNotifyControlThread.Start();

            // 開一個線程來更新數據類群信息 
            UpdateVDataThread = new Thread(UpdateVDataThreadFunc);
            UpdateVDataThread.Start();

            StartAccept(null);

            //未完成
            //守護線程
            //m_daemonThread = new DaemonThread(this);
        }
Example #24
0
        /// <summary>
        /// 轉發訂閱號回覆到用戶
        /// </summary>
        /// <param name="DataTerminal"></param>
        /// <param name="DataGroup"></param>
        /// <param name="DataBody"></param>
        /// <param name="DataGUID"></param>
        protected void SendSubServiceFeedbackToUser(string DataTerminal, string DataGroup, string DataBody, string MsgGUID)
        {
            // 抓出群成員
            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
            {
                conn.OpenConnection();
                try
                {
                    // 記錄到數據庫中
                    // DataType == "L"時, DataTerminalName為Pull消息子分類(表名)
                    string MsgNO = this.InsertSubSrvFeedback(conn, m_userToken.BindingUser.ID, DataBody, DataGroup, DataTerminal, "0", "", "1", "0", MsgGUID);
                    if (MsgNO.Length > 0)
                    {
                        #region " 發給接收人 "

                        DataTable UserList = conn.OpenDataTable("select a.msg_to from lrmsgstate a (nolock) where a.msg_no=" + MsgNO + " and a.msg_state='0'", CommandType.Text);
                        if (UserList.Rows.Count > 0)
                        {
                            string Users = "";
                            //系統將訊息轉發給群成員(以發送者的帳號) 
                            //問題: 1.只有帳號沒有姓名.Client無法顯示姓名
                            //      2.沒有發送日期和時間
                            // PC 和 Mobile 要用到的信息.提前打包好,沒必要放到for循環里去做
                            List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(DataBody, "5", "", "", DataGroup, MsgGUID, MsgNO);

                            foreach (DataRow User in UserList.Rows)
                            {
                                #region " PC Client "

                                Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.PcUserTokenList, "SendSubServiceFeedbackToUser");

                                #endregion

                                #region " Mobile Client "

                                Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.MobileUserTokenList, "SendSubServiceFeedbackToUser");

                                #endregion
                            }
                            // 去掉最後一個逗號
                            if (Users.Length > 0)
                            {
                                Users = Users.Substring(0, Users.Length - 1);
                                // 標記為已讀                    
                                DateTime now = DateTime.Now;
                                string ymd = now.ToString("yyyy/MM/dd");
                                string time = now.ToString("HH:mm:ss");
                                conn.ExecuteSQL("update a set a.msg_state='1',a.ie_lymd='" + ymd + "',a.ie_ltime='" + time + "' from lrmsgstate a where a.msg_no=" + MsgNO + " and a.msg_state='0' and a.msg_to in (" + Users + ")");
                            }
                        }
                        UserList.Dispose();
                        UserList = null;

                        #endregion

                        // 轉發完再發回執
                        // 向發送者發送回執7-03
                        //this.PushFeedback(MsgGUID, MsgNO);
                    }
                    conn.CloseConnection();
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
        }
Example #25
0
        /// <summary>
        /// 排程處理用戶狀態推送
        /// </summary>
        private void StateNotifyControlThreadFunc()
        {
            SQLHelper conn = new SQLHelper(DBInfo);
            //DataTable ContactsList;
            //SocketUserToken UserToken;
            string UserID, UserState, UserSignature;
            byte[] UserAvatar = null;
            List<string> Contacts;
            try
            {
                conn.OpenConnection();

                while (true)
                {
                    Thread.Sleep(100);
                    try
                    {
                        //當前設備數據更新隊列
                        ServerStatistics.CurentUserState_Queue = StateNotifyQueue.Count;
                        //最高設備數據更新隊列
                        if (ServerStatistics.MaxUserState_Queue < ServerStatistics.CurentUserState_Queue)
                            ServerStatistics.MaxUserState_Queue = ServerStatistics.CurentUserState_Queue;
                        //可用的用戶狀態推送線程
                        ServerStatistics.IdleUserState_PushQueue = StateNofityThreadsQueue.Count;

                        while (StateNotifyQueue.Count > 0 && StateNofityThreadsQueue.Count > 0)
                        {
                            //有用戶在排隊
                            //User = (UserSocket)StateNotifyQueue.Dequeue();
                            List<object> objs = (List<object>)StateNotifyQueue.Dequeue();
                            if (objs != null)
                            {
                                //UserToken = (SocketUserToken)objs[0];
                                UserID = objs[0].ToString();
                                UserState = objs[1].ToString();
                                UserSignature = objs[2].ToString();
                                Contacts = (List<string>)objs[3];
                                //Added by Donnie on 2016/04/27
                                UserAvatar = (byte[])objs[4]; //頭像數據
                                //if (UserToken.BindingUser.Contacts.Count == 0)
                                //{
                                //    ContactsList = GetContacts(conn, UserToken.BindingUser.ID);
                                //    if (ContactsList.Rows.Count > 0)
                                //    {
                                //        foreach (DataRow Contact in ContactsList.Rows)
                                //        {
                                //            //加入聯絡人(防呆自己加自己)
                                //            if (UserToken.BindingUser.ID != Contact["contact_id"].ToString())
                                //                UserToken.BindingUser.Contacts.Add(Contact["contact_id"].ToString());
                                //        }
                                //    }
                                //}
                                if (Contacts.Count > 0)
                                {
                                    if (StateNofityThreadsQueue.Count > 0)
                                    {
                                        //有空閒的線程可以使用
                                        //取出線程和用戶并開始推送操作
                                        Thread StateNotifyThread = (Thread)StateNofityThreadsQueue.Dequeue();
                                        if (StateNotifyThread != null)
                                        {
                                            //LogHelper.WriteLog("StateNotifyControlThreadFunc", "已取得線程資源,即將推送" + User.ID + "的狀態" + UserState);

                                            List<object> paras = new List<object>();
                                            //不再打包UserToken,因為如果是用戶離線操作,有可能狀態還沒有推送前UserToken就已經被消除了.推送時會因無法抓UserToken而報錯.
                                            //paras.Add(UserToken);
                                            paras.Add(UserID); //ID string
                                            paras.Add(UserState); //狀態 string
                                            paras.Add(UserSignature); //簽名 string
                                            paras.Add(Contacts); //聯絡人清單 List<string>
                                            paras.Add(UserAvatar); //頭像數據
                                            paras.Add(StateNotifyThread); //工作線程 Thread
                                            if (!StateNotifyThread.IsAlive)
                                            {
                                                StateNotifyThread = new Thread(new ParameterizedThreadStart(StateNotifyThreadFunc));
                                            }
                                            StateNotifyThread.Start(paras);
                                        }
                                        else
                                        {
                                            // 沒有取到線程資源,把對象重新放入隊列
                                            StateNotifyQueue.Enqueue(objs);
                                            LogHelper.WriteLog("StateNotifyControlThreadFunc", "沒有取到線程資源,把對象重新放入隊列.");
                                        }
                                    }
                                    else
                                    {
                                        // 沒有可用的線程資源,把對象重新放入隊列
                                        StateNotifyQueue.Enqueue(objs);
                                        LogHelper.WriteLog("StateNotifyControlThreadFunc", "沒有可用的線程資源,把對象重新放入隊列.");
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog("StateNotifyControlThreadFunc()", "執行用戶狀態推送時:" + (ex != null ? ex.Message : ""));
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("StateNotifyControlThreadFunc()", "執行用戶狀態推送時:" + (ex != null ? ex.Message : ""));
            }
            finally
            {
                if (conn != null)
                    conn.CloseConnection();
            }
        }
Example #26
0
        protected string ProcessTransferFileRequest(string Target, string DataType, string DataTerminal, string DataGroup, string DataGUID, string DataBody, string DataTerminalName)
        {
            string MsgNO = "";
            // 記錄到數據庫中
            using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
            {
                conn.OpenConnection();
                try
                {
                    //msg_doctype = 0:即時文件 1:文字 2:離線文件
                    //msg_docstate = 3:等待接收 2:傳送完成 
                    if (DataGroup != "O")
                    {
                        MsgNO = this.InsertMsg(conn, Target, DataBody, "", DataTerminal, "1", "", "0", "3", DataGUID, false, true);
                    }
                    else
                    {
                        MsgNO = this.InsertMsg(conn, Target, DataBody, "", DataTerminal, "1", "", "2", "2", DataGUID, false, true);
                    }
                    conn.CloseConnection();

                    if (MsgNO.Length > 0)
                    {
                        //接收者

                        PushMessage("", ParseProtocol.ConvertMsgToByte(DataBody, DataType, Target, DataTerminalName, DataGroup, DataGUID, MsgNO), DataTerminal, m_asyncSocketServer.PcUserTokenList, "ProcessTransferFileRequest");

                        #region " 處理同一帳號多個端登錄的轉發. "

                        if (DataGroup == "O" && m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP)
                        {
                            //來自Mobile(Web)端消息.
                            //檢查相同帳號Web端有沒有登錄,有就轉發一次.
                            #region " PC Client "

                            PushRoaming(Target, ParseProtocol.ConvertMsgToByte(DataBody, "P", DataTerminal, "", "", DataGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList);

                            #endregion
                        }

                        #endregion
                    }
                }
                catch
                {
                    conn.CloseConnection();
                }
            }
            return MsgNO;
        }
Example #27
0
        public static string[] ProcessRequest(object[] requestData, string SrvNO, string DBAlias)
        {
            //20條數據分一頁,防止單條消息超過4000byte
            int ROWS_PER_PAGE = 20;
            //返回數組 0=type ; 1=終端; 2=群號; 3=時間; 4=消息ID; 5=消息內容 6=終端姓名
            string result = "無效命令." + Environment.NewLine + "請使用命令: ? 查詢本訂閱號提供的服務.";
            //訂閱號業務處理分類處理
            //訂閱號,命令Code,操作腳本
            //switch (GroupID)
            //{
            //    case "888":
            //        //在這里加入解析命令并處理
            //        //Do something
            //        result = "SubSrv #1:Hello";
            //        break;
            //    case "D151100318":
            //        //在這里加入解析命令并處理
            //        //Do something
            //        result = "SubSrv #2:Hello";
            //        break;
            //}
            if (requestData[5].ToString().Trim() == "?" || requestData[5].ToString().Trim() == "?")
            {
                #region " ?命令:返回訂閱號的命令清單 "

                using (SQLHelper conn = new SQLHelper(DBAlias))
                {
                    conn.OpenConnection();
                    try
                    {
                        DataTable Rec = conn.OpenDataTable("select cmd_code,cmd_remk,cmd_format from lxsubcmds (nolock) where srv_no='" + SrvNO + "' and cmd_visible='Y' order by cmd_seq", CommandType.Text);
                        conn.CloseConnection();

                        if (Rec.Rows.Count > 0)
                        {
                            //<table>
                            //    <caption>訂閱號命令清單</caption>
                            //    <thead>
                            //        <tr>
                            //            <th>命令代碼</th>
                            //            <th>命令說明</th>
                            //            <th>命令格式</th>
                            //        </tr>
                            //    </thead>
                            //    <tbody>
                            //        <tr>
                            //            <td>FILE</td>
                            //            <td>列出EIS報表代號及名稱清單</td>
                            //            <td>FILE</td>
                            //        </tr>
                            //        <tr>
                            //            <td>EIS</td>
                            //            <td>取得EIS系統資料</td>
                            //            <td>EIS EIC-ID-003 A169 2016/06</td>
                            //        </tr>
                            //    </tbody>
                            //</table>

                            string h5_Table_Format = "<table>" + "\r\n" +
                                                     "    <caption>訂閱號命令清單{0}</caption>" + "\r\n" +
                                                     "    <thead>" + "\r\n" +
                                                     "        <tr>" + "\r\n" +
                                                     "            <th style=\"width:80px;\">命令代碼</th>" + "\r\n" +
                                                     "            <th style=\"width:auto;\">命令說明</th>" + "\r\n" +
                                                     "            <th style=\"width:auto;\">命令格式</th>" + "\r\n" +
                                                     "        </tr>" + "\r\n" +
                                                     "    </thead>" + "\r\n" +
                                                     "    <tbody>" + "\r\n" +
                                                     "        {1}" + "\r\n" +
                                                     "    </tbody>" + "\r\n" +
                                                     "</table>";
                            string h5_tBody_Format = "<tr>" + "\r\n" +
                                                     "    {0}" + "\r\n" +
                                                     "</tr>";
                            result = "";
                            //string h5_Head_Value = "";
                            List<string> CmdRows = new List<string>();
                            for (int i = 0; i < Rec.Rows.Count; i++)
                            {
                                //result += Rec.Rows[i]["cmd_code"].ToString() + " : " + Rec.Rows[i]["cmd_remk"].ToString();
                                //h5_Head_Value += string.Format(h5_tBody_Format, "<td>" + Rec.Rows[i]["cmd_code"].ToString() + "</td>" +
                                //                                                "<td>" + Rec.Rows[i]["cmd_remk"].ToString() + "</td>" +
                                //                                                "<td>" + Rec.Rows[i]["cmd_format"].ToString() + "</td>") + Environment.NewLine;
                                //if (i + 1 < Rec.Rows.Count)
                                //    result += Environment.NewLine;

                                CmdRows.Add(string.Format(h5_tBody_Format, "<td>" + Rec.Rows[i]["cmd_code"].ToString() + "</td>" +
                                                                           "<td>" + Rec.Rows[i]["cmd_remk"].ToString() + "</td>" +
                                                                           "<td>" + Rec.Rows[i]["cmd_format"].ToString() + "</td>"));
                            }
                            //得到消息條數
                            string[] Results = new string[CmdRows.Count / ROWS_PER_PAGE + 1];
                            int k = 0;
                            for (int i = 0; i < CmdRows.Count; i++)
                            {
                                if (i % ROWS_PER_PAGE == 0 && i > 0)
                                {
                                    //達到分頁數,產生一條消息.
                                    Results[k] = string.Format(h5_Table_Format, "(" + (k+1).ToString() + ")", result);
                                    k++;
                                    result = "";
                                }
                                result += CmdRows[i] + Environment.NewLine;
                            }
                            if (result.Length > 0 && k < Results.Length)
                            {
                                //最後一筆
                                Results[k] = string.Format(h5_Table_Format, "(" + (k + 1).ToString() + ")", result);
                            }
                            CmdRows.Clear();
                            CmdRows = null;
                            //result = "本訂閱號命令如下:" + Environment.NewLine + result;
                            //result = string.Format(h5_Table_Format, h5_Head_Value);

                            //直接返回
                            return Results;
                        }
                        else
                        {
                            result = "本訂閱號暫無命令可使用.";
                        }
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog("ProcessRequest()", "處理?命令時:" + (ex != null ? ex.Message : ""));
                        conn.CloseConnection();
                    }
                }

                #endregion
            }
            else if (requestData[5].ToString().Trim().IndexOf("<Data Name=") > -1 &&
                     requestData[5].ToString().Trim().IndexOf("</Data>") > -1)
            {
                //格式化輸入不響應
                result = "";
            }
            else
            {
                #region  " 其他命令 "
                //select cmd_operation,cmd_paras from lxsubcmds (nolock) where srv_no='3737' and cmd_code='PO'
                using (SQLHelper conn = new SQLHelper(DBAlias))
                {
                    conn.OpenConnection();
                    try
                    {
                        //空格分隔
                        string[] tmp = requestData[5].ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        //命令
                        string CMD = tmp[0].Trim().ToUpper();
                        //規則:
                        //1.用命令得到訂閱號表名及欄位.
                        DataTable Rec = conn.OpenDataTable("select cmd_operation,cmd_paras,srv_table,filter_key,order_key,top_num,template_no,match_type,multi_value,cmd_format,rows_paging from lxsubcmds (nolock) where srv_no='" + SrvNO + "' and cmd_code='" + CMD + "'", CommandType.Text);
                        if (Rec.Rows.Count > 0)
                        {
                            //得到分頁靈敏
                            ROWS_PER_PAGE = int.Parse(Rec.Rows[0]["rows_paging"].ToString());
                            if (ROWS_PER_PAGE <= 0) ROWS_PER_PAGE = 20;
                            //2.得到權限分組代號
                            DataTable subRec = conn.OpenDataTable("select permission_group from lxpermissions (nolock) where srv_no='" + SrvNO + "' and lx_account='" + requestData[1].ToString().Trim() + "'", CommandType.Text);
                            if (subRec.Rows.Count > 0)
                            {
                                string andWhere = "", OrderBy = "";
                                //1=等於;2=以..開始
                                string MathType = Rec.Rows[0]["match_type"].ToString();
                                string SrvTable = Rec.Rows[0]["srv_table"].ToString();
                                string CMDFormat = Rec.Rows[0]["cmd_format"].ToString();
                                string PermissionGroup = "";
                                for (int i = 0; i < subRec.Rows.Count; i++)
                                {
                                    PermissionGroup += "'" + subRec.Rows[i]["permission_group"].ToString() + "'";
                                    if (i + 1 < subRec.Rows.Count)
                                        PermissionGroup += ",";
                                }
                                //3.根據表名得到參數名
                                subRec = conn.OpenDataTable("select tb_colno,tb_colna,tb_coltype from lxsubtemplates (nolock) where srv_no='" + SrvNO + "' and srv_table='" + SrvTable + "' and template_no='" + Rec.Rows[0]["template_no"].ToString() + "' order by paras_order", CommandType.Text);
                                if (subRec.Rows.Count > 0)
                                {
                                    //4.得到訂閱號表數據(lxsub01,lxsub02...) (根據filter_key,order_key,top_num抓數據)
                                    result = GetFilterAndOrder(tmp, CMD, Rec, ref andWhere, ref OrderBy, MathType);
                                    if (result.Length == 0)
                                    {
                                        DataTable dataRec = conn.OpenDataTable("select " + Rec.Rows[0]["top_num"].ToString() + " * from " + SrvTable + " (nolock) where srv_no='" + SrvNO + "' and group_no in (" + PermissionGroup + ")" + andWhere + OrderBy, CommandType.Text);
                                        if (dataRec.Rows.Count > 1)
                                        {
                                            #region " 明細 "

                                            string h5_Table_Format = "<table>" + "\r\n" +
                                                                     "    <caption>{0}{1}</caption>" + "\r\n" +
                                                                     "    <thead>" + "\r\n" +
                                                                     "        <tr>" + "\r\n" +
                                                                     "            {2}" + "\r\n" +
                                                                     "        </tr>" + "\r\n" +
                                                                     "    </thead>" + "\r\n" +
                                                                     "    <tbody>" + "\r\n" +
                                                                     "        {3}" + "\r\n" +
                                                                     "    </tbody>" + "\r\n" +
                                                                     "</table>";
                                            string h5_tBody_Format = "<tr>" + "\r\n" +
                                                                     "    {0}" + "\r\n" +
                                                                     "</tr>";
                                            //得到cmd_operation,并把轉換為橫多行模式
                                            //<table>
                                            //    <caption>項目回報表</caption>
                                            //    <thead>
                                            //        <tr>
                                            //            <th>序號</th>
                                            //            <th>工作人員</th>
                                            //            <th>項目編號</th>
                                            //            <th>項目名稱</th>
                                            //            <th>立案日期</th>
                                            //            <th>備注</th>
                                            //        </tr>
                                            //    </thead>
                                            //    <tbody>
                                            //        <tr>
                                            //            <td>0001</td>
                                            //            <td>D003842</td>
                                            //            <td>T0000001</td>
                                            //            <td>樂行樂信底層開發</td>
                                            //            <td>2016/01/01</td>
                                            //            <td>進行中</td>
                                            //        </tr>
                                            //        <tr>
                                            //            <td>0002</td>
                                            //            <td>D003842</td>
                                            //            <td>T0000002</td>
                                            //            <td>樂行樂信第三方應用開發</td>
                                            //            <td>2016/01/01</td>
                                            //            <td>進行中</td>
                                            //        </tr>
                                            //    </tbody>
                                            //</table>
                                            string h5_Table_Caption = ""; //{0}
                                            string h5_Head_Value = "";    //{1}
                                            result = "";
                                            List<string> CmdRows = new List<string>();
                                            //得到顯示列表樣式
                                            DataTable ListFormat = XmlStrToDataTable(subRec, Rec.Rows[0]["cmd_operation"].ToString());
                                            decimal width = 0;
                                            if (ListFormat != null && ListFormat.Rows.Count > 0)
                                            {
                                                h5_Table_Caption = HtmlConvertor(ListFormat.ExtendedProperties["Caption"].ToString());
                                                //<th>序號</th>
                                                foreach (DataRow dr in ListFormat.Rows)
                                                {
                                                    try
                                                    {
                                                        width = decimal.Parse(dr["tb_colwidth"].ToString());
                                                    }
                                                    catch
                                                    {
                                                        width = 0;
                                                    }
                                                    if (width <= 0) width = 80;
                                                    h5_Head_Value += "<th style=\"width:" + width.ToString() + "px;\">" + dr["tb_colna"].ToString() + "</th>";
                                                }
                                                //開始填表身數據
                                                string colno = "";
                                                //string h5_Body_Value = "";    //{0}
                                                string h5_Body_Value_tmp = "";
                                                foreach (DataRow row in dataRec.Rows)
                                                {
                                                    h5_Body_Value_tmp = "";
                                                    for (int i = 0; i < subRec.Rows.Count; i++)
                                                    {
                                                        colno = subRec.Rows[i]["tb_colno"].ToString();
                                                        if (subRec.Rows[i]["tb_coltype"].ToString() == "1")
                                                        {
                                                            //FTP文件
                                                            h5_Body_Value_tmp += "<td>" + "ftp://lx.lorom.net.cn/ProductAttatchments/ToDoList/" + SrvNO + "/" + row[colno].ToString() + "</td>";
                                                        }
                                                        else
                                                        {
                                                            h5_Body_Value_tmp += "<td>" + HtmlConvertor(row[colno].ToString()) + "</td>";
                                                        }
                                                    }
                                                    CmdRows.Add(string.Format(h5_tBody_Format, h5_Body_Value_tmp));
                                                    //h5_Body_Value += string.Format(h5_tBody_Format, h5_Body_Value_tmp) + "\r\n";
                                                }

                                                //得到消息條數
                                                string[] Results = new string[(CmdRows.Count % ROWS_PER_PAGE == 0) ? (CmdRows.Count / ROWS_PER_PAGE) : (CmdRows.Count / ROWS_PER_PAGE + 1)];
                                                int k = 0;
                                                for (int i = 0; i < CmdRows.Count; i++)
                                                {
                                                    if (i % ROWS_PER_PAGE == 0 && i > 0)
                                                    {
                                                        //達到分頁數,產生一條消息.
                                                        Results[k] = string.Format(h5_Table_Format, h5_Table_Caption, 
                                                                                                    "(" + (k + 1).ToString() + ")", 
                                                                                                    h5_Head_Value,
                                                                                                    result);
                                                        k++;
                                                        result = "";
                                                    }
                                                    result += CmdRows[i] + Environment.NewLine;
                                                }
                                                if (result.Length > 0 && k < Results.Length)
                                                {
                                                    //最後一筆
                                                    Results[k] = string.Format(h5_Table_Format, h5_Table_Caption,
                                                                                                "(" + (k + 1).ToString() + ")",
                                                                                                h5_Head_Value,
                                                                                                result);
                                                }
                                                CmdRows.Clear();
                                                CmdRows = null;

                                                //組成最後的列表
                                                //result = string.Format(h5_Table_Format, h5_Table_Caption,
                                                //                                        h5_Head_Value,
                                                //                                        h5_Body_Value);
                                                //直接返回一條或多條.
                                                return Results;

                                            }
                                            else
                                            {
                                                LogHelper.WriteLog("ProcessRequest()", "嘗試命令:" + CMD + "的cmd_operation參數設置錯誤.");
                                                result = "對不起,當前命令暫時無法使用.";
                                            }

                                            #endregion
                                        }
                                        else if (dataRec.Rows.Count == 1)
                                        {
                                            #region " 單筆 "

                                            string[] paras = new string[subRec.Rows.Count];
                                            string colno = "";
                                            for (int i = 0; i < subRec.Rows.Count; i++)
                                            {
                                                colno = subRec.Rows[i]["tb_colno"].ToString();
                                                if (subRec.Rows[i]["tb_coltype"].ToString() == "1")
                                                {
                                                    //FTP文件
                                                    paras[i] = "ftp://lx.lorom.net.cn/ProductAttatchments/ToDoList/" + SrvNO + "/" + dataRec.Rows[0][colno].ToString();
                                                }
                                                else
                                                {
                                                    paras[i] = HtmlConvertor(dataRec.Rows[0][colno].ToString());
                                                }
                                            }
                                            result = string.Format(Rec.Rows[0]["cmd_operation"].ToString(), paras);

                                            #endregion
                                        }
                                        else
                                        {
                                            result = "對不起,暫時無法取得任何數據.";
                                        }
                                    }
                                    else
                                    {
                                        //命令格式不正確
                                        result += CMDFormat;
                                        return new string[] { result };
                                    }
                                }
                                else
                                {
                                    LogHelper.WriteLog("ProcessRequest()", "命令:" + CMD + "的cmd_operation參數設置錯誤.");
                                    result = "對不起,當前命令暫時無法使用.";
                                }

                                #region " 舊邏輯 "

                                //if (Rec.Rows[0]["multi_value"].ToString() == "Y" && subRec.Rows.Count > 0)
                                //{
                                //    #region " 明細類數據 "

                                //    //4.得到訂閱號表數據(lxsub01,lxsub02...) (根據filter_key,order_key,top_num抓數據)
                                //    result = GetFilterAndOrder(tmp, CMD, Rec, ref andWhere, ref OrderBy, MathType);
                                //    if (result.Length > 0)
                                //    {
                                //        //命令格式不正確
                                //        result += CMDFormat;
                                //        return result;
                                //    }

                                //    DataTable dataRec = conn.OpenDataTable("select * from " + SrvTable + " (nolock) where srv_no='" + SrvNO + "' and group_no in (" + PermissionGroup + ")" + andWhere + OrderBy, CommandType.Text);
                                //    if (dataRec.Rows.Count > 0)
                                //    {
                                //        string colno = "", colna = "";
                                //        result = "";
                                //        foreach (DataRow row in dataRec.Rows)
                                //        {
                                //            for (int i = 0; i < subRec.Rows.Count; i++)
                                //            {
                                //                colno = subRec.Rows[i]["tb_colno"].ToString();
                                //                colna = subRec.Rows[i]["tb_colna"].ToString();
                                //                if (subRec.Rows[i]["tb_coltype"].ToString() == "1")
                                //                {
                                //                    //FTP文件
                                //                    result += colna + "ftp://lx.lorom.net.cn/ProductAttatchments/ToDoList/" + SrvNO + "/" + row[colno].ToString();
                                //                }
                                //                else
                                //                {
                                //                    result += colna + row[colno].ToString();
                                //                }
                                //                if (i + 1 < subRec.Rows.Count)
                                //                {
                                //                    result += "    ";
                                //                }
                                //            }
                                //            result += Environment.NewLine;
                                //        }
                                //        result = string.Format(Rec.Rows[0]["cmd_operation"].ToString(), result);
                                //    }
                                //    else
                                //    {
                                //        result = "對不起,暫時無法取得任何數據.";
                                //    }

                                //    #endregion
                                //}
                                //else
                                //{
                                //    #region " 單筆數據 "

                                //    if (subRec.Rows.Count == float.Parse(Rec.Rows[0]["cmd_paras"].ToString()) && subRec.Rows.Count > 0)
                                //    {
                                //        //參數設置正確
                                //        //4.得到訂閱號表數據(lxsub01,lxsub02...) (根據filter_key,order_key,top_num抓數據)
                                //        result = GetFilterAndOrder(tmp, CMD, Rec, ref andWhere, ref OrderBy, MathType);
                                //        if (result.Length > 0)
                                //        {
                                //            //命令格式不正確
                                //            result += CMDFormat;
                                //            return result;
                                //        }

                                //        DataTable dataRec = conn.OpenDataTable("select " + Rec.Rows[0]["top_num"].ToString() + " * from " + SrvTable + " (nolock) where srv_no='" + SrvNO + "' and group_no in (" + PermissionGroup + ")" + andWhere + OrderBy, CommandType.Text);
                                //        if (dataRec.Rows.Count > 0)
                                //        {
                                //            string[] paras = new string[subRec.Rows.Count];
                                //            string colno = "";
                                //            for (int i = 0; i < subRec.Rows.Count; i++)
                                //            {
                                //                colno = subRec.Rows[i]["tb_colno"].ToString();
                                //                if (subRec.Rows[i]["tb_coltype"].ToString() == "1")
                                //                {
                                //                    //FTP文件
                                //                    paras[i] = "ftp://lx.lorom.net.cn/ProductAttatchments/ToDoList/" + SrvNO + "/" + dataRec.Rows[0][colno].ToString();
                                //                }
                                //                else
                                //                {
                                //                    paras[i] = dataRec.Rows[0][colno].ToString();
                                //                }
                                //            }
                                //            result = string.Format(Rec.Rows[0]["cmd_operation"].ToString(), paras);
                                //        }
                                //        else
                                //        {
                                //            result = "對不起,暫時無法取得任何數據.";
                                //        }
                                //    }
                                //    else
                                //    {
                                //        LogHelper.WriteLog("ProcessRequest()", "命令:" + CMD + "的cmd_operation參數設置錯誤.");
                                //        result = "對不起,當前命令暫時無法使用.";
                                //    }

                                //    #endregion
                                //}

                                #endregion
                            }
                            else
                            {
                                result = "對不起,當前帳號無權限使用此命令.";
                            }
                        }
                        conn.CloseConnection();
                    }
                    catch (Exception ex)
                    {
                        result = "訂閱號服務出現異常,請稍後再試.";
                        LogHelper.WriteLog("ProcessRequest()", "處理: " + requestData[5].ToString() + " 命令時:" + (ex != null ? ex.Message : ""));
                        conn.CloseConnection();
                    }
                }

                #endregion
            }
            return new string[] { result };
        }
Example #28
0
        protected void SendImage(string DataTerminal, string DataGroup, byte[] DataImage, string DataTerminalName, string DataGUID)
        {
            //處理邏輯: 將圖片生成一個縮略圖,存放到lrtdmsg.msg_img里. 再將完整圖片數據放到對照表lrmsgimg里.
            //          用戶點擊縮略圖再下載完整圖片
            try
            {
                int width = ServerConst.Thumbnail_Width, height = ServerConst.Thumbnail_Height;
                System.Drawing.Image thumbnail = ImageHelper.BytesToImage(ImageHelper.DeCompress(DataImage));
                if (thumbnail.Width < width)
                    width = thumbnail.Width;
                if (thumbnail.Height < height)
                    height = thumbnail.Height;
                byte[] ThumbImage = ImageHelper.Compress(ImageHelper.Thumbnail(thumbnail, width, height, ServerConst.Thumbnail_Quality, "WH"));
                thumbnail.Dispose();
                thumbnail = null;

                string curUserID = m_userToken.BindingUser.ID;
                //DataTerminal是接收人帳號
                //DataTerminalName是發送人姓名
                using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
                {
                    conn.OpenConnection();
                    try
                    {
                        // 記錄到數據庫中
                        string MsgNO = InsertImage(conn, curUserID, DataImage, DataGroup, DataTerminal, "1", DataGUID, ThumbImage);
                        if (MsgNO.Length > 0)
                        {
                            //沒改完,要用特殊方式打包
                            //開始發送
                            if (DataGroup.Length == 0)
                            {
                                //向人發
                                SendP2PImage(curUserID, DataTerminalName, DataTerminal, ThumbImage, conn, DataGUID, MsgNO);
                            }
                            else
                            {
                                //向群發
                                SendGroupImage(DataTerminal, DataGroup, ThumbImage, DataTerminalName, conn, DataGUID, MsgNO);
                            }
                            // 轉發完再發回執
                            // 向發送者發送回執7-03
                            PushFeedback(DataGUID, MsgNO);
                        }
                        conn.CloseConnection();
                    }
                    catch
                    {
                        conn.CloseConnection();
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("SendImage", ex.Message);
            }
        }
Example #29
0
 /// <summary>
 /// 通話日誌記錄
 /// </summary>
 private void UpdateAudioLog(string SenderID, string ReceiverID, DateTime StartDT, DateTime EndDT, string logGUID, string logSIP, string devSName, string devSMac, string logRIP, string devRName, string devRMac)
 {
     using (SQLHelper conn = new SQLHelper(m_asyncSocketServer.DBInfo))
     {
         conn.OpenConnection();
         try
         {
             DateTime LogDT = DateTime.Now;
             TimeSpan TS = EndDT.Subtract(StartDT);
             conn.ExecuteSQL("insert into lxaudiolog (sender_id,receiver_id,ie_ymd,ie_time,log_sdate,log_stime,log_edate,log_etime,log_durtime,log_guid,log_sip,dev_sname,dev_smac,log_rip,dev_rname,dev_rmac) " + "\r\n" +
                             "values('" + SenderID + "','" + ReceiverID + "','" + LogDT.ToString("yyyy/MM/dd") + "','" + LogDT.ToString("HH:mm:ss") + "'," + "\r\n" +
                             "'" + StartDT.ToString("yyyy/MM/dd") + "','" + StartDT.ToString("HH:mm:ss") + "'," +
                             "'" + EndDT.ToString("yyyy/MM/dd") + "','" + EndDT.ToString("HH:mm:ss") + "'," + (int)TS.TotalSeconds + "," +
                             "'" + logGUID + "','" + logSIP + "','" + devSName + "','" + devSMac + "','" + logRIP + "','" + devRName + "','" + devRMac + "')");
             conn.CloseConnection();
         }
         catch (Exception ex)
         {
             conn.CloseConnection();
             throw ex;
         }
     }
 }
Example #30
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
            //{ }
        }