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; }
/// <summary> /// 訂閱號服務端登錄 /// </summary> /// <param name="UserID"></param> /// <param name="DataTerminalName"></param> /// <param name="DataGroup"></param> /// <param name="DataText"></param> /// <param name="userToken"></param> /// <param name="UserTokenList"></param> /// <returns></returns> private bool DoSubServiceLogin(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("DoSubServiceLogin()", "執行向" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 發送強制離線[不允許自動重連]消息時:" + (ex != null ? ex.Message : "")); } finally { Monitor.Exit(curSkt); } } else { //如果到這里說明之前登陸的對象已經死鎖 LogHelper.WriteLog("DoSubServiceLogin()", "嘗試使用Monitor.TryEnter鎖定" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 時失敗."); } } catch (SocketException ex) { LogHelper.WriteLog("DoSubServiceLogin()", "向" + DataGroup + "用戶: " + UserID + " [" + curIPAddress + "] 發送離線[不允許自動重連]消息時:" + (ex != null ? ex.Message : "")); } try { //運行到這里時,有可能客戶端收到7-00之後主動斷開連接,則會觸發CloseClientSocket. if (!ExistsUser.Closing) { //ExistsUser.Closing = true; CloseClientSocket(ExistsUser); } LogHelper.WriteLog("DoSubServiceLogin", string.Format("因相同帳號再次登錄,強制先登錄的用戶{0} [{1}] 下線.", UserID, curIPAddress)); UpdateUserLog(UserID, "1", "0", "因相同帳號再次登陸而強制離線.", "", null); } catch (SocketException ex) { LogHelper.WriteLog("DoSubServiceLogin()", "嘗試關閉" + 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("DoSubServiceLogin()", DataGroup + "用戶:" + UserID + "登錄失敗"); } catch (SocketException ex) { LogHelper.WriteLog("DoSubServiceLogin()", "發送登陸失敗信息時" + (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("DoSubServiceLogin()", "發送登錄成功信息時" + (ex != null ? ex.Message : "")); } if (Passed) { //設置對象狀態 userToken.BindingUser = new User(); userToken.BindingUser.State = User.UserStates.Online; userToken.BindingUser.Role = User.UserRole.SubService; userToken.BindingUser.Mobile = User.UserMobileType.None; userToken.BindingUser.ID = UserID; //Mac userToken.BindingUser.MacAddr = DataTerminalName; if (Passed) { //添加到正在執行的列表中 if (UserTokenList.ContainsKey("#" + UserID + "#")) { ExistsUser = UserTokenList["#" + UserID + "#"]; if (ExistsUser != null) { try { LogHelper.WriteLog("DoSubServiceLogin", string.Format("加入在線人員列表時發現已有同名帳號在里面,強制用戶{0} [{1}] 下線.", UserID, ExistsUser.ConnectSocket.RemoteEndPoint)); if (!ExistsUser.Closing) { //ExistsUser.Closing = true; CloseClientSocket(ExistsUser); } } catch (SocketException ex) { LogHelper.WriteLog("DoSubServiceLogin()", "嘗試關閉" + 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; }