/// <summary> /// 構造函數 /// </summary> /// <param name="mConn">SQLHelper對象</param> /// <param name="SQL">SQL語句</param> /// <param name="OptionType">如何操作</param> /// <param name="TableName">Table 別名</param> internal RecordSet(SQLHelper mConn, string SQL, tagUpdateMode OptionType, string TableName) { string mySQL = SQL; if (SQL.IndexOf(' ') < 0) { if (OptionType == tagUpdateMode.RT_Insert) mySQL = "select * from " + mySQL + " where 1=0 "; else mySQL = "select * from " + mySQL; } this.conn = mConn; this._ICursor = this.conn.OpenDataTableForUpdate(mySQL, out myDataAdapter, TableName); this.myDataAdapter.RowUpdated += new SqlRowUpdatedEventHandler(myDataAdapter_RowUpdated); this.myDataAdapter.RowUpdating += new SqlRowUpdatingEventHandler(myDataAdapter_RowUpdating); this.mEditMode = tagUpdateMode.RT_Browse; }
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; }
//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 { } }
//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(); } }
//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(); } }
private DataTable GetUnreadMsgs(SQLHelper conn, string UserID, string Source) { string SQL = ""; switch (Source) { case "M": //消息 SQL = " select b.td_no,b.msg_date,b.msg_time,b.msg_text,b.msg_img,b.msg_no, " + "\r\n" + " b.msg_from,isnull(c.user_name,'') as user_name,b.msg_guid,b.msg_doctype,b.msg_type " + " from lrmsgstate a (nolock) " + "\r\n" + " join lrtdmsg b (nolock) on a.msg_no=b.msg_no " + "\r\n" + " left join lrtduser c (nolock) on b.msg_from=c.user_no " + "\r\n" + " where a.msg_to='" + UserID + "' and a.msg_state='0' " + "\r\n" + " order by b.td_no,b.msg_no"; break; //case "C": // //命令 // SQL = // " select b.td_no,b.cmd_date,b.cmd_time,b.cmd_text,b.cmd_no, " + "\r\n" + // " b.cmd_user,isnull(c.user_name,'') as user_name,b.cmd_guid " + // " from lrcmdstate a (nolock) " + "\r\n" + // " join lrtdcmd b (nolock) on a.cmd_no=b.cmd_no " + "\r\n" + // " left join lrtduser c (nolock) on b.cmd_user=c.user_no " + "\r\n" + // " where a.cmd_to='" + UserID + "' and a.cmd_state='0' " + "\r\n" + // " order by b.td_no,b.cmd_no"; // break; case "S": //系統消息 SQL = " select b.sys_date,b.sys_time,b.sys_type,b.sys_objtype,b.sys_remk,b.sys_id,b.sys_user,b.sys_objid " + " from lrsysmsgstate a (nolock) " + "\r\n" + " join lrsysmsg b (nolock) on a.sys_id=b.sys_id " + "\r\n" + " where a.sysmsg_to='" + UserID + "' and a.sysmsg_state='0' " + "\r\n" + " order by b.sys_id"; break; } return conn.OpenDataTable(SQL, CommandType.Text); }
private void DoUpdateUserState(SQLHelper conn, string UserID, string State) { try { conn.ExecuteSQL("update a set a.user_state='" + State + "' from lrtduser a where user_no='" + UserID + "'"); } catch (Exception ex) { throw ex; } }
/// <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(); } } }
public string InsertMsg(SQLHelper conn, string User, string Msg, string td_no, string msg_to, string MsgType, string MsgPullType, string GUID, bool ForTest, bool IsPushMode) { return InsertMsg(conn, User, Msg, td_no, msg_to, MsgType, MsgPullType, "1", "0", GUID, ForTest, IsPushMode); }
/// <summary> /// /// </summary> /// <param name="conn"></param> /// <param name="User"></param> /// <param name="Voice"></param> /// <param name="td_no"></param> /// <param name="msg_to"></param> /// <param name="MsgType">0=群消息,1=個人消息</param> /// <param name="GUID"></param> /// <returns></returns> public string InsertVoice(SQLHelper conn, string User, byte[] Voice, string td_no, string msg_to, string MsgType, string GUID, string VoiceSeconds) { try { long SeqNO = 0; string SQL = "select msg_no from lrtdmsg (nolock) where msg_guid='" + GUID + "'"; DataTable dtSeq = conn.OpenDataTable(SQL, CommandType.Text); if (dtSeq.Rows.Count > 0) { //重復就不寫入 return dtSeq.Rows[0]["msg_no"].ToString(); } else //lock (Ticket) 這里先不鎖,單純靠SQL的鎖機制來處理 { dtSeq = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '1',@seqNO output select @seqNO", CommandType.Text); if (dtSeq.Rows.Count > 0) { SeqNO = long.Parse(dtSeq.Rows[0][0].ToString()); } } if (SeqNO > 0) { DateTime now = DateTime.Now; string ymd = now.ToString("yyyy/MM/dd"); string time = now.ToString("HH:mm:ss"); SQL = "insert into lrtdmsg (ie_ymd,ie_time,ie_user,td_no,msg_from,msg_to,msg_date,msg_time,msg_text,msg_no,msg_type,msg_doctype,msg_docstate,msg_guid) " + "values('" + ymd + "','" + time + "','" + User + "','" + td_no + "','" + User + "','" + msg_to + "','" + ymd + "','" + time + "',N'" + VoiceSeconds + "'," + SeqNO + ",'" + MsgType + "','6','0','" + GUID + "')"; conn._Transaction = conn._Connection.BeginTransaction(); conn.ExecuteSQL(SQL); SQL = "insert into lrmsgimg (ie_ymd,ie_time,ie_user,msg_no,msg_img) " + "values('" + ymd + "','" + time + "','" + User + "'," + SeqNO + ",@voice)"; //寫入完整圖 conn.ExecuteSQLImage(SQL, "@voice", Voice); if (td_no.Length > 0) { // ##發群組## //寫表頭Owner SQL = " insert into lrmsgstate (msg_no,msg_to,msg_state)" + "\r\n" + " select a.msg_no,b.td_owner,'0' " + "\r\n" + " from lrtdmsg a(nolock)" + "\r\n" + " join lrtd00h b(nolock) on a.td_no = b.td_no " + "\r\n" + " where a.msg_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + " and b.td_owner <> '" + User + "'"; conn.ExecuteSQL(SQL); //寫表身相關人 SQL = " insert into lrmsgstate (msg_no,msg_to,msg_state)" + "\r\n" + " select a.msg_no,b.td_member,'0' " + "\r\n" + " from lrtdmsg a(nolock)" + "\r\n" + " join lrtd00d1 b(nolock) on a.td_no = b.td_no " + "\r\n" + " join lrtd00h c (nolock) on b.td_no=c.td_no " + "\r\n" + " where a.msg_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + " and b.td_member <> '" + User + "' and b.td_member <> c.td_owner "; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','" + td_no + "','','G','" + ymd + "','" + time + "'," + SeqNO); } else if (msg_to.Length > 0) { // ##發給個人## SQL = "insert into lrmsgstate (msg_no,msg_to,msg_state) values('" + SeqNO + "','" + msg_to + "','0')"; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','','" + msg_to + "','P','" + ymd + "','" + time + "'," + SeqNO); } conn._Transaction.Commit(); } return SeqNO.ToString(); //return new string[] { curTDID, ymd, time }; } catch (System.Exception ex) { //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + ex.Message); LogHelper.WriteLog("InsertVoice()", "將音頻寫入數據庫時:" + (ex != null ? ex.Message : "")); conn._Transaction.Rollback(); throw ex; } }
/// <summary> /// 轉發群消息 /// </summary> /// <param name="DeviceType">P=PC;M=Mobile(Web);A=APP</param> /// <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> private void SendGroupVoice(string DataTerminal, string DataGroup, string DataTerminalName, SQLHelper conn, string MsgGUID, string MsgNO, string VoiceSeconds) { 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(VoiceSeconds, "R", DataTerminal, DataTerminalName, DataGroup, MsgGUID, MsgNO); foreach (DataRow User in UserList.Rows) { #region " PC Client " Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.PcUserTokenList, "SendGroupVoice"); #endregion #region " Mobile Client " Users = PushMessage(Users, msgs, User["msg_to"].ToString(), m_asyncSocketServer.MobileUserTokenList, "SendGroupVoice"); #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 " Mobile Client " PushRoaming(DataTerminal, ParseProtocol.ConvertMsgToByte(VoiceSeconds, "R", "", "", 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(VoiceSeconds, "R", "", "", DataGroup, MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList); #endregion } }
/// <summary> /// 轉人到人音頻 /// </summary> /// <param name="fromUserID"></param> /// <param name="fromUserName"></param> /// <param name="toUserID"></param> /// <param name="conn"></param> /// <param name="MsgGUID"></param> /// <param name="MsgNO"></param> private void SendP2PVoice(string fromUserID, string fromUserName, string toUserID, SQLHelper conn, string MsgGUID, string MsgNO, string VoiceSeconds) { string Users = ""; if (toUserID.Length > 0) { List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(VoiceSeconds, "R", fromUserID, fromUserName, "", MsgGUID, MsgNO); #region " PC Client " Users = PushMessage(Users, msgs, toUserID, m_asyncSocketServer.PcUserTokenList, "SendP2PVoice"); #endregion #region " Mobile Client " Users = PushMessage(Users, msgs, toUserID, m_asyncSocketServer.MobileUserTokenList, "SendP2PVoice"); #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 + ")"); } } //處理同一帳號多個端登錄的轉發. 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(fromUserID, ParseProtocol.ConvertMsgToByte(VoiceSeconds, "R", toUserID, "", "", 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(fromUserID, ParseProtocol.ConvertMsgToByte(VoiceSeconds, "R", toUserID, "", "", MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList); #endregion } }
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); } }
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); } }
/// <summary> /// 轉人到人消息 /// </summary> /// <param name="DeviceType">P=PC;M=Mobile(Web);A=第三方</param> /// <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 SendP2PMessage(string fromUserID, string fromUserName, string toUserID, string DataBody, SQLHelper conn, string MsgGUID, string MsgNO, string DataType) { string Users = ""; if (toUserID.Length > 0) { List<byte[]> msgs = ParseProtocol.ConvertMsgToByte(DataBody, DataType, fromUserID, fromUserName, "", MsgGUID, MsgNO); #region " PC Client " Users = PushMessage(Users, msgs, toUserID, m_asyncSocketServer.PcUserTokenList, "SendP2PMessage"); #endregion #region " Web Client (不向Web端發送) " ////userSkt = _ws_transmit_tb[toUserID] as Socket; //recUser = _ws_transmit_tb[toUserID] as UserSocket; //if (recUser != null) //{ // userSkt = recUser.Socket; // byte[] msg = WebConvertMethod.ConvertMsgToByte(DataBody, DataType, fromUserID, fromUserName, "", MsgNO); // try // { // //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息 // lock (userSkt) // { // userSkt.Send(msg); // //SendData(userSkt, msg); // } // send = true;//標記已經發送成功 // } // catch (SocketException ex) // { // //掉線了,直接干掉. // try // { // LogHelper.WriteLog("SendP2PMessage", "發消息給手機用戶:" + toUserID + "時發生異常,斷開連接." + (ex != null ? ex.Message : "")); // //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):catch (SocketException)", "發消息給用戶:" + toUserID + "時發生異常,斷開連接."); // 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(toUserID); // Thread userThread = _ws_thread_tb[toUserID] as Thread; // userThread.Abort(); // //線程池不會被遍歷,不鎖. // _ws_thread_tb.Remove(toUserID); // } // catch // { } // } //} #endregion #region " Mobile Client " Users = PushMessage(Users, msgs, toUserID, m_asyncSocketServer.MobileUserTokenList, "SendP2PMessage"); #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 + ")"); } } //處理同一帳號多個端登錄的轉發. if (m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.PC || m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.AudioCall || m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP) { //來自PC端消息. //檢查相同帳號Mobile(Web)端有沒有登錄,有就轉發一次. #region " Web Client (不發) " ////userSkt = _ws_transmit_tb[fromUserID] as Socket; //recUser = _ws_transmit_tb[fromUserID] as UserSocket; //if (recUser != null) //{ // userSkt = recUser.Socket; // // 系統將訊息轉發給群成員(以發送者的帳號) // //問題: 1.只有帳號沒有姓名.Client無法顯示姓名 // // 2.沒有發送日期和時間 // byte[] msg = WebConvertMethod.ConvertMsgToByte(DataBody, "A", fromUserID, fromUserName, toUserID, MsgNO); // try // { // //鎖住線程,保證本次發送完成後其他線程才能對此用戶發送消息 // lock (userSkt) // { // userSkt.Send(msg); // //SendData(userSkt, msg); // } // } // catch (SocketException ex) // { // //掉線了,直接干掉. // try // { // LogHelper.WriteLog("SendP2PMessage", "發消息給手機用戶:" + fromUserID + "時發生異常,斷開連接." + (ex != null ? ex.Message : "")); // //clsClientLog.WriteLog(clsClientLog.LogType.Error, "WebThreadFunc(object obj):catch (SocketException)", "發消息給Mobile端用戶:" + fromUserID + "時發生異常,斷開連接."); // if (userSkt.Connected) // { // userSkt.Shutdown(SocketShutdown.Both); // //userSkt.Disconnect(false); // } // userSkt.Close(); // #region " 聯絡人狀態變更 " // //通知在線的聯絡人當前用戶改變了狀態 // //recUser.SetUserState("6"); // //UpdateUserLog(recUser.ID, "1", "1", "異常登出"); // //如果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(fromUserID); // Thread userThread = _ws_thread_tb[fromUserID] as Thread; // userThread.Abort(); // //線程池不會被遍歷,不鎖. // _ws_thread_tb.Remove(fromUserID); // } // catch // { } // } //} #endregion #region " Mobile Client " PushRoaming(fromUserID, ParseProtocol.ConvertMsgToByte(DataBody, DataType, toUserID, "", "", 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.AudioCall || m_userToken.BindingUser.Role == LxTcpServer.Core.User.UserRole.APP) { //來自Mobile(Web)端消息. //檢查相同帳號Web端有沒有登錄,有就轉發一次. #region " PC Client " PushRoaming(fromUserID, ParseProtocol.ConvertMsgToByte(DataBody, DataType, toUserID, "", "", MsgGUID, MsgNO, "R"), m_asyncSocketServer.PcUserTokenList); #endregion } }
/// <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; } } }
/// <summary> /// 更新日誌及用戶檔 /// </summary> /// <param name="conn"></param> /// <param name="UserID">用戶帳號</param> /// <param name="logType">日誌類別:0=登錄;1=登退;2=改簽名;3=改頭像</param> /// <param name="logDevice">設備</param> /// <param name="logText">日誌描述或用戶簽名</param> /// <param name="logIP">IP地址</param> /// <param name="devName">設備名稱</param> /// <param name="devMac">設備網卡Mac</param> /// <param name="logAvatar">頭像數據</param> private void DoUpdateUserLog(SQLHelper conn, string UserID, string logType, string logDevice, string logText, string logIP, string devName, string devMac, byte[] logAvatar) { try { DateTime LogDT = DateTime.Now; //Added by Donne on 2016/06/04 //加入devName //Added by Donne on 2016/06/07 //加入devMac conn.ExecuteSQL("insert into lrlxlog (user_no,log_date,log_time,log_type,log_device,log_text,log_ip,dev_name,dev_mac) " + "\r\n" + "values('" + UserID + "','" + LogDT.ToString("yyyy/MM/dd") + "','" + LogDT.ToString("HH:mm:ss") + "','" + logType + "','" + logDevice + "',N'" + logText.Replace("'", "''") + "','" + logIP + "',N'" + devName.Replace("'", "''") + "','" + devMac + "')"); if (logType == "2" || logType == "3") { if (logType == "2") { //改簽名 conn.ExecuteSQL("update a set a.user_msg=N'" + logText.Replace("'", "''") + "' from lrtduser a where user_no='" + UserID + "'"); } else if (logType == "3") { //改頭像 conn.ExecuteSQLImage("update a set a.user_img=@img from lrtduser a where user_no='" + UserID + "'", "@img", logAvatar); } //更新聯絡人時間stamp conn.ExecuteSQL("update a set a.log_time='" + LogDT.ToString("yyyyMMddHHmmssfff") + "' from lrcontact_log a join lrcontact b (nolock) on a.user_no=b.user_no and a.contact_id=b.contact_id where b.contact_id='" + UserID + "'"); conn.ExecuteSQL("insert into lrcontact_log (user_no,contact_id,log_time,log_do) " + "\r\n" + "select a.user_no,a.contact_id,'" + LogDT.ToString("yyyyMMddHHmmssfff") + "','U' from lrcontact a (nolock) " + "\r\n" + "where a.contact_id ='" + UserID + "' and not exists(select 1 from lrcontact_log b (nolock) where a.user_no=b.user_no and a.contact_id=b.contact_id)"); } } catch (Exception ex) { throw ex; } }
/// <summary> /// /// </summary> /// <param name="conn"></param> /// <param name="User"></param> /// <param name="Msg"></param> /// <param name="td_no"></param> /// <param name="msg_to"></param> /// <param name="MsgType">0=群消息,1=個人消息</param> /// <param name="MsgPullType">拉取式消息子分類(空=普通消息;LXSubject=主題;自定義表名=什麼都可以)</param> /// <param name="MsgDocType">0=File;1=Text;2=Offline File;3=Image;4=Mail;5=Quake</param> /// <param name="MsgDocState">文件狀態.</param> /// <param name="GUID"></param> /// <param name="ForTest"></param> /// <param name="IsPushMode"></param> /// <returns></returns> public string InsertMsg(SQLHelper conn, string User, string Msg, string td_no, string msg_to, string MsgType, string MsgPullType, string MsgDocType, string MsgDocState, string GUID, bool ForTest, bool IsPushMode) { try { long SeqNO = 0; string tbMsg = "lrtdmsg"; string tbState = "lrmsgstate"; if (ForTest) { tbMsg = "lrtdmsg_test"; tbState = "lrmsgstate_test"; } string SQL = "select msg_no from " + tbMsg + " (nolock) where msg_guid='" + GUID + "'"; DataTable dtSeq = conn.OpenDataTable(SQL, CommandType.Text); if (dtSeq.Rows.Count > 0) { //重復就不寫入 return dtSeq.Rows[0]["msg_no"].ToString(); } else //lock (Ticket) 這里先不鎖,單純靠SQL的鎖機制來處理 { string SeqCode = "1"; // 正式單 if (ForTest) SeqCode = "2"; dtSeq = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '" + SeqCode + "',@seqNO output select @seqNO", CommandType.Text); if (dtSeq.Rows.Count > 0) { SeqNO = long.Parse(dtSeq.Rows[0][0].ToString()); } } if (SeqNO > 0) { DateTime now = DateTime.Now; string ymd = now.ToString("yyyy/MM/dd"); string time = now.ToString("HH:mm:ss"); conn._Transaction = conn._Connection.BeginTransaction(); //string maxID = GetMaxMsgID(conn, td_no); //int curNumber = int.Parse(maxID) + 1; //maxID = curNumber.ToString().PadLeft(5, '0'); //string curTDID = Guid.NewGuid().ToString().Replace("-", "").ToUpper(); //Added by Donnie on 2016/05/26 //增加MsgPullType SQL = "insert into " + tbMsg + " (ie_ymd,ie_time,ie_user,td_no,msg_from,msg_to,msg_date,msg_time,msg_text,msg_no,msg_type,msg_datatype,msg_doctype,msg_docstate,msg_guid) " + "values('" + ymd + "','" + time + "','" + User + "','" + td_no + "','" + User + "','" + msg_to + "','" + ymd + "','" + time + "',N'" + Msg.Replace("'", "''") + "'," + SeqNO + ",'" + MsgType + "','" + MsgPullType + "','" + MsgDocType + "','" + MsgDocState + "','" + GUID + "')"; conn.ExecuteSQL(SQL); //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + Msg); if (td_no.Length > 0) { // ##發群組## // Added by Donnie on 2016/05/13 // 只有Push模式的群才向lrmsgstate里寫記錄 // Added by Donnie on 2016/05/31 // Pull模式只向群主轉發 // Modified by Donnie on 2016/06/01 // 最終商定Pull消息不向任何群成員推送(包括群主) if (IsPushMode) { //寫表頭Owner SQL = " insert into " + tbState + " (ie_ymd,ie_time,ie_user,msg_no,msg_to,msg_state)" + "\r\n" + " select '" + ymd + "','" + time + "','" + User + "',a.msg_no,b.td_owner,'0' " + "\r\n" + " from " + tbMsg + " a(nolock)" + "\r\n" + " join lrtd00h b(nolock) on a.td_no = b.td_no " + "\r\n" + " where a.msg_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + " and b.td_owner <> '" + User + "'"; conn.ExecuteSQL(SQL); //寫表身相關人 SQL = " insert into " + tbState + " (ie_ymd,ie_time,ie_user,msg_no,msg_to,msg_state)" + "\r\n" + " select '" + ymd + "','" + time + "','" + User + "',a.msg_no,b.td_member,'0' " + "\r\n" + " from " + tbMsg + " a(nolock)" + "\r\n" + " join lrtd00d1 b(nolock) on a.td_no = b.td_no " + "\r\n" + " join lrtd00h c (nolock) on b.td_no=c.td_no " + "\r\n" + " where a.msg_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + " and b.td_member <> '" + User + "' and b.td_member <> c.td_owner "; conn.ExecuteSQL(SQL); } // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','" + td_no + "','','G','" + ymd + "','" + time + "'," + SeqNO); } else if (msg_to.Length > 0) { // ##發給個人## SQL = "insert into " + tbState + " (msg_no,msg_to,msg_state) values('" + SeqNO + "','" + msg_to + "','0')"; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','','" + msg_to + "','P','" + ymd + "','" + time + "'," + SeqNO); } conn._Transaction.Commit(); } return SeqNO.ToString(); } catch (System.Exception ex) { //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + ex.Message); LogHelper.WriteLog("StartUp()", "將消息寫入數據庫時:" + (ex != null ? ex.Message : "")); conn._Transaction.Rollback(); throw ex; } }
/// <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; } } }
public string InsertCmd(SQLHelper conn, string User, string Msg, string td_no, string GUID) { try { long SeqNO = 0; string SQL = "select cmd_no from lrtdcmd (nolock) where cmd_guid='" + GUID + "'"; DataTable dtSeq = conn.OpenDataTable(SQL, CommandType.Text); if (dtSeq.Rows.Count > 0) { //重復就不寫入 return dtSeq.Rows[0]["cmd_no"].ToString(); } else { dtSeq = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '3',@seqNO output select @seqNO", CommandType.Text); if (dtSeq.Rows.Count > 0) { SeqNO = long.Parse(dtSeq.Rows[0][0].ToString()); } } if (SeqNO > 0) { DateTime now = DateTime.Now; string ymd = now.ToString("yyyy/MM/dd"); string time = now.ToString("HH:mm:ss"); //conn._Transaction = conn._Connection.BeginTransaction(); SQL = "insert into lrtdcmd (ie_ymd,ie_time,ie_user,td_no,cmd_user,cmd_text,cmd_date,cmd_time,cmd_no,cmd_guid) " + "values('" + ymd + "','" + time + "','" + User + "','" + td_no + "','" + User + "',N'" + Msg.Replace("'", "''") + "','" + ymd + "','" + time + "'," + SeqNO + ",'" + GUID + "')"; conn.ExecuteSQL(SQL); //if (td_no.Length > 0) //{ // // ##發群組## // //寫表頭Owner // SQL = // " insert into lrcmdstate (cmd_no,cmd_to,cmd_state)" + "\r\n" + // " select a.cmd_no,b.td_owner,'0' " + "\r\n" + // " from lrtdcmd a(nolock)" + "\r\n" + // " join lrtd00h b(nolock) on a.td_no = b.td_no " + "\r\n" + // " where a.cmd_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + // " and b.td_owner <> '" + User + "'"; // conn.ExecuteSQL(SQL); // //寫表身相關人 // SQL = // " insert into lrcmdstate (cmd_no,cmd_to,cmd_state)" + "\r\n" + // " select a.cmd_no,b.td_member,'0' " + "\r\n" + // " from lrtdcmd a(nolock)" + "\r\n" + // " join lrtd00d1 b(nolock) on a.td_no = b.td_no " + "\r\n" + // " join lrtd00h c (nolock) on b.td_no=c.td_no " + "\r\n" + // " where a.cmd_guid ='" + GUID + "' and a.td_no = '" + td_no + "'" + // " and b.td_member <> '" + User + "' and b.td_member <> c.td_owner "; // conn.ExecuteSQL(SQL); //} //conn._Transaction.Commit(); } return SeqNO.ToString(); } catch (System.Exception ex) { //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + ex.Message); LogHelper.WriteLog("StartUp()", "將命令寫入數據庫時:" + (ex != null ? ex.Message : "")); //conn._Transaction.Rollback(); throw ex; } }
private DataTable GetContacts(SQLHelper conn, string UserID) { //暫時改為只抓好友. //string SQL = "select contact_id from " + "\r\n" + // "( " + "\r\n" + // " select contact_id from lrcontact (nolock) where user_no='" + UserID + "' " + "\r\n" + // " union " + "\r\n" + // " --我是owner時抓所有member " + "\r\n" + // " select b.td_member as contact_id from lrtd00h a (nolock) " + "\r\n" + // " join lrtd00d1 b (nolock) on a.td_no=b.td_no " + "\r\n" + // " where a.td_owner='" + UserID + "' " + "\r\n" + // " union " + "\r\n" + // " --我不是owner時抓所有owner " + "\r\n" + // " select a.td_owner as contact_id from lrtd00h a (nolock) " + "\r\n" + // " join lrtd00d1 b (nolock) on a.td_no=b.td_no " + "\r\n" + // " where a.td_owner<>'" + UserID + "' and b.td_member='" + UserID + "' " + "\r\n" + // " union " + "\r\n" + // " --我不是owner時抓所有member " + "\r\n" + // " select x.td_member as contact_id from lrtd00d1 x (nolock) " + "\r\n" + // " where x.td_no in " + "\r\n" + // " ( " + "\r\n" + // " select a.td_no from lrtd00h a (nolock) " + "\r\n" + // " join lrtd00d1 b (nolock) on a.td_no=b.td_no " + "\r\n" + // " where a.td_owner<>'" + UserID + "' and b.td_member='" + UserID + "' " + "\r\n" + // " ) and x.td_member<>'" + UserID + "' " + "\r\n" + // ") a"; //Added by Donnie on 2016/04/29 //把自己的好友和添加了自己為好友的人都作為聯絡人 //string SQL = "select contact_id from lrcontact (nolock) where user_no='" + UserID + "' "; string SQL = "select contact_id from ( " + "\r\n" + " select contact_id as contact_id from lrcontact (nolock) where user_no='" + UserID + "' " + "\r\n" + " union " + "\r\n" + " select user_no as contact_id from lrcontact (nolock) where contact_id='" + UserID + "' " + "\r\n" + ") a"; return conn.OpenDataTable(SQL, CommandType.Text); }
public string InsertSysMsg(SQLHelper conn, string User, string Msg, string SysType, string SysObjType, string td_no, string msg_to, string GUID) { try { long SeqNO = 0; string SQL; //lock (Ticket) 這里先不鎖,單純靠SQL的鎖機制來處理 //{ DataTable dtSeq = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '5',@seqNO output select @seqNO", CommandType.Text); if (dtSeq.Rows.Count > 0) { SeqNO = long.Parse(dtSeq.Rows[0][0].ToString()); } //} if (SeqNO > 0) { DateTime now = DateTime.Now; string ymd = now.ToString("yyyy/MM/dd"); string time = now.ToString("HH:mm:ss"); conn._Transaction = conn._Connection.BeginTransaction(); if (SysType == "1") { //撤回消息操作(msg_doctype='1' 切换回文字类别 SQL = "update a set a.msg_text=N'" + Msg.Replace("'", "''") + "',a.msg_docstate='2',a.msg_doctype='1' from lrtdmsg a where msg_guid='" + GUID + "'"; conn.ExecuteSQL(SQL); } SQL = "insert into lrsysmsg (ie_ymd,ie_time,ie_user,sys_date,sys_time,sys_user,sys_id,sys_type,sys_objtype,sys_objid,sys_remk) " + "values('" + ymd + "','" + time + "','" + User + "','" + ymd + "','" + time + "','" + User + "','" + SeqNO + "','" + SysType + "','" + SysObjType + "','" + GUID + "',N'" + Msg.Replace("'", "''") + "')"; conn.ExecuteSQL(SQL); //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + Msg); if (td_no.Length > 0) { // ##發群組## //寫表頭Owner SQL = " insert into lrsysmsgstate (sys_id,sysmsg_to,sysmsg_state)" + "\r\n" + " select '" + SeqNO + "',a.td_owner,'0' " + "\r\n" + " from lrtd00h a(nolock) " + "\r\n" + " where a.td_no = '" + td_no + "' and a.td_owner <> '" + User + "'"; conn.ExecuteSQL(SQL); //寫表身相關人 SQL = " insert into lrsysmsgstate (sys_id,sysmsg_to,sysmsg_state)" + "\r\n" + " select '" + SeqNO + "',b.td_member,'0' " + "\r\n" + " from lrtd00d1 b(nolock) " + "\r\n" + " join lrtd00h c (nolock) on b.td_no=c.td_no " + "\r\n" + " where c.td_no = '" + td_no + "'" + " and b.td_member <> '" + User + "' and b.td_member <> c.td_owner "; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','" + td_no + "','','G','" + ymd + "','" + time + "'," + SeqNO); } else if (msg_to.Length > 0) { // ##發給個人## SQL = "insert into lrsysmsgstate (sys_id,sysmsg_to,sysmsg_state) values('" + SeqNO + "','" + msg_to + "','0')"; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','','" + msg_to + "','P','" + ymd + "','" + time + "'," + SeqNO); } conn._Transaction.Commit(); } return SeqNO.ToString(); //return new string[] { curTDID, ymd, time }; } catch (System.Exception ex) { //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + ex.Message); LogHelper.WriteLog("StartUp()", "將系統消息寫入數據庫時:" + (ex != null ? ex.Message : "")); conn._Transaction.Rollback(); throw ex; } }
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); }
/// <summary> /// /// </summary> /// <param name="conn"></param> /// <param name="User"></param> /// <param name="Msg"></param> /// <param name="td_no"></param> /// <param name="msg_to"></param> /// <param name="MsgType">0=群消息,1=個人消息</param> /// <param name="MsgPullType">拉取式消息子分類(空=普通消息;LXSubject=主題;自定義表名=什麼都可以)</param> /// <param name="MsgDocType">0=File;1=Text;2=Offline File;3=Image;4=Mail;5=Quake</param> /// <param name="MsgDocState">文件狀態.</param> /// <param name="GUID"></param> /// <param name="ForTest"></param> /// <param name="IsPushMode"></param> /// <returns></returns> public string InsertSubSrvFeedback(SQLHelper conn, string User, string Msg, string td_no, string msg_to, string MsgType, string MsgPullType, string MsgDocType, string MsgDocState, string GUID) { try { long SeqNO = 0; string SQL = "select msg_no from lrtdmsg (nolock) where msg_guid='" + GUID + "'"; DataTable dtSeq = conn.OpenDataTable(SQL, CommandType.Text); if (dtSeq.Rows.Count > 0) { //重復就不寫入 return dtSeq.Rows[0]["msg_no"].ToString(); } else //lock (Ticket) 這里先不鎖,單純靠SQL的鎖機制來處理 { dtSeq = conn.OpenDataTable("declare @seqNO bigint exec GetMessageNO '1',@seqNO output select @seqNO", CommandType.Text); if (dtSeq.Rows.Count > 0) { SeqNO = long.Parse(dtSeq.Rows[0][0].ToString()); } } if (SeqNO > 0) { DateTime now = DateTime.Now; string ymd = now.ToString("yyyy/MM/dd"); string time = now.ToString("HH:mm:ss"); conn._Transaction = conn._Connection.BeginTransaction(); SQL = "insert into lrtdmsg (ie_ymd,ie_time,ie_user,td_no,msg_from,msg_to,msg_date,msg_time,msg_text,msg_no,msg_type,msg_datatype,msg_doctype,msg_docstate,msg_guid) " + "values('" + ymd + "','" + time + "','" + User + "','" + td_no + "','" + User + "','" + msg_to + "','" + ymd + "','" + time + "',N'" + Msg.Replace("'", "''") + "'," + SeqNO + ",'" + MsgType + "','" + MsgPullType + "','" + MsgDocType + "','" + MsgDocState + "','" + GUID + "')"; conn.ExecuteSQL(SQL); // 寫接收人 SQL = " insert into lrmsgstate (ie_ymd,ie_time,ie_user,msg_no,msg_to,msg_state)" + "\r\n" + " values('" + ymd + "','" + time + "','" + User + "'," + SeqNO + ",'" + msg_to + "','0')"; conn.ExecuteSQL(SQL); // Added by Donnie on 2016/06/01 // 更新Recents //@USER_NO varchar(50), @TD_NO varchar(50),@MSG_TO varchar(50), @DATA_TYPE varchar(1), @RC_DATE varchar(10), @RC_TIME varchar(8), @MSG_NO numeric(28,0) conn.ExecuteSQL("exec UpdateRecents '" + User + "','" + td_no + "','','G','" + ymd + "','" + time + "'," + SeqNO); conn._Transaction.Commit(); } return SeqNO.ToString(); } catch (System.Exception ex) { //clsClientLog.WriteLog(clsClientLog.LogType.Error, "InsertMsg", "發送的消息是:" + ex.Message); LogHelper.WriteLog("StartUp()", "將消息寫入數據庫時:" + (ex != null ? ex.Message : "")); conn._Transaction.Rollback(); throw ex; } }
/// <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(); } }
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; } } }
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 }; }
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> 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; } } }
/// <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(); // } //} }