/// <summary> /// UDP 로 전달받은 메세지를 Client 로 알림 /// </summary> /// <param name="userId">알림 받을 UserID</param> /// <param name="message">알림 받을 메세지</param> internal void SendMessageNotiftyToClient(byte[] messageBytes, string userId) { FACInfo facInfo = FACContainer.FindFACInfo(userId); if (facInfo == null) { return; } SocketAsyncEventArgs sendEventArgs = facInfo.sendEventArgs; if (sendEventArgs == null) { return; } /// 전문 By Pass /// 버퍼로 복사 DataHoldingUserToken sendToken = (DataHoldingUserToken)sendEventArgs.UserToken; sendToken.dataToSend = new byte[messageBytes.Length]; Buffer.BlockCopy(messageBytes, 0, sendToken.dataToSend, 0, messageBytes.Length); this.SendMessage(sendEventArgs); }
/// <summary> /// Accept, Login 된 client 정보 제거 /// </summary> /// <param name="e">SAEA 객체</param> public static bool Remove(SocketAsyncEventArgs e) { lock (FACContainer.LockThis) { IPEndPoint ep = null; DataHoldingUserToken dToken = e.UserToken as DataHoldingUserToken; ep = dToken.IpEndPt; //IPEndPoint ep = e.RemoteEndPoint as IPEndPoint; //if (dToken != null) //{ // ep = dToken.IpEndPt; //} //else //{ // AcceptOpUserToken aToken = e.UserToken as AcceptOpUserToken; // ep = aToken.IpEndPt; //} //if(e.AcceptSocket == null) // return false; //EndPoint endPoint = e.AcceptSocket.RemoteEndPoint; //DataHoldingUserToken receiveSendToken = (e.UserToken as DataHoldingUserToken); //EndPoint endPoint = e.AcceptSocket.RemoteEndPoint; if (ep == null) { return(false); } FACInfo facInfo = null; if (!FACContainer.Instance.FacList.TryGetValue(ep, out facInfo)) { return(false); } // 사용자맵 정보 제거 List <EndPoint> mapEndPoint; if (FACContainer.Instance.FacMapList.TryGetValue(facInfo.USER_ID, out mapEndPoint)) { if (mapEndPoint.Count == 1) { FACContainer.Instance.FacMapList.Remove(facInfo.USER_ID); } else { FACContainer.Instance.FacMapList[facInfo.USER_ID].Remove(ep); } } // FAC 정보 제거 if (FACContainer.Instance.FacList.ContainsKey(ep)) { FACContainer.Instance.FacList.Remove(ep); } return(true); } }
/// <summary> /// Login 된 client 정보로 수정 /// </summary> /// <param name="client">client socket (검색용)</param> /// <param name="userId">등록할 UserID</param> /// <param name="userName">등록할 User 이름</param> public static bool Update(Socket client, string userId, string userName) { lock (FACContainer.LockThis) { /// 유효성 검사 EndPoint endPoint = client.RemoteEndPoint; FACInfo facInfo = FACContainer.FindFACInfo(endPoint); if (facInfo == null) { return(false); } /// 정보 수정 facInfo.USER_ID = userId; facInfo.USER_NAME = userName; // Dictionary Map 추가 (검색용) if (FACContainer.Instance.FacMapList.ContainsKey(userId) == false) { List <EndPoint> mapEndPoint = new List <EndPoint>(); mapEndPoint.Add(endPoint); FACContainer.Instance.FacMapList.Add(userId, mapEndPoint); } else { FACContainer.Instance.FacMapList[userId].Add(client.RemoteEndPoint); } return(true); } }
/// <summary> /// Accept 한 client 추가 (로그인 아님) /// </summary> /// <param name="client">client socket</param> /// <param name="recvEventArgs">등록할 Receive SAEA 객체</param> /// <param name="sendEventArgs">등록할 Send SAEA 객체</param> public static bool Add(Socket client, SocketAsyncEventArgs recvEventArgs, SocketAsyncEventArgs sendEventArgs) { lock (FACContainer.LockThis) { FACInfo fac = new FACInfo(); fac.Socket = client; fac.recvEventArgs = recvEventArgs; fac.sendEventArgs = sendEventArgs; // MODIFY : KIMCG - 20140802 // fac가 이미 존재시 계속 로그인 실패하기 때문에 Remove가 필요함. //if (FACContainer.Instance.FacList.ContainsKey(client.RemoteEndPoint) == true) //{ // return false; //} //else //{ // FACContainer.Instance.FacList.Add(client.RemoteEndPoint, fac); // return true; //} // Dictionary 추가 if (FACContainer.Instance.FacList.ContainsKey(client.RemoteEndPoint)) { FACContainer.Instance.FacList.Remove(client.RemoteEndPoint); } FACContainer.Instance.FacList.Add(client.RemoteEndPoint, fac); return(true); } }
/// <summary> /// 로그인 /// </summary> private MessageStream MessageLogin(MessageReader reader, SocketAsyncEventArgs receiveSendEventArgs) { MessageStream response = null; string user_id = reader.GetParam(0); string user_pw = reader.GetParam(1); string user_name = ""; string recv_faxbox_id = ""; string send_faxbox_id = ""; /// ipep.ToString() : 100.100.106.230:2038 /// ipep.Address.ToString() : 100.100.106.230 IPEndPoint ipep = (IPEndPoint)receiveSendEventArgs.AcceptSocket.RemoteEndPoint; RESULT result = DbModule.Instance.FAS_LoginAgentClient(user_id, user_pw, ipep.ToString(), ref user_name, ref recv_faxbox_id, ref send_faxbox_id); if (result == RESULT.F_DB_NOTEXIST_USER_ID || result == RESULT.F_DB_PASSWORD_MISMATCH) { response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, false, "사용자 ID가 없거나 암호가 잘못되었습니다."); } else if (result == RESULT.SUCCESS || result == RESULT.F_DB_LOGIN_DUPLICATED) { /// /CLOSE 전문 발송 (중복 로그인) if (result == RESULT.F_DB_LOGIN_DUPLICATED) { FACInfo oldFacInfo = FACContainer.FindFACInfo(user_id); if (oldFacInfo != null) { if (this.OnLoginDuplicated != null) { this.OnLoginDuplicated(oldFacInfo); } } } DataHoldingUserToken receiveSendToken = (receiveSendEventArgs.UserToken as DataHoldingUserToken); /// Login 된 Client 로 추가 FACContainer.Update(receiveSendEventArgs.AcceptSocket, user_id, user_name); response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, "성공"); response.AddPrameters(reader.GetParam(0)); response.AddPrameters(user_name); response.AddPrameters(recv_faxbox_id); response.AddPrameters(send_faxbox_id); response.AddPrameters(((int)Config.CLIENT_ALIVE_INTERVAL).ToString()); response.AddPrameters(((int)Config.CLIENT_LIMIT_RESPONSE_TIME).ToString()); response.AddPrameters(Config.HOME_PATH_HTTP); } else { response = MessageStream.Response(MessagePacketNameEnum.LOGIN, reader.Header, false, result.ToString()); } return(response); }
/// <summary> /// 중복 로그인 처리 /// </summary> /// <param name="userId"></param> private void messageParsing_OnLoginDuplicated(FACInfo loginedFacInfo) { SocketAsyncEventArgs sendEventArgs = loginedFacInfo.sendEventArgs; if (sendEventArgs == null) { return; } this.SendMessageToClient(sendEventArgs, MessagePacketNameEnum.CLOSE, loginedFacInfo.USER_ID); }
/// <summary> /// 지정시간동안 Client 요청이 없으면 강제 종료 처리 /// </summary> private void AliveCheckSockets_ThreadEntry() { Dictionary <EndPoint, FACInfo> acceptedList; //bool isalive = true; while (true) { Thread.Sleep(1000 * 10); lock (FACContainer.LockThis) { acceptedList = new Dictionary <EndPoint, FACInfo>(FACContainer.AcceptedList); } foreach (KeyValuePair <EndPoint, FACInfo> kvPair in acceptedList) { try { FACInfo info = FACContainer.FindFACInfo(kvPair.Key); if (info == null) { continue; } if (Config.SERVER_LIMIT_RESPONSE_TIME > 0 && DateTime.Now.Subtract(info.LastRequestTime).TotalSeconds > Config.SERVER_LIMIT_RESPONSE_TIME) { // 종료 처리 SocketListener.Log.WRN(string.Format("AliveCheckSockets_ThreadEntry() : Arrive timeout. {0}/{1}" , DateTime.Now.Subtract(info.LastRequestTime).TotalSeconds , Config.SERVER_LIMIT_RESPONSE_TIME)); // 이미 삭제 되었을때 Exception 발생 if (info.Socket != null) { SocketListener.Log.WRN(string.Format("{0}|Socket Disconnect.", kvPair.Key.ToString())); try { info.Socket.Disconnect(false); } catch { } } FACContainer.Remove(info.recvEventArgs); FACContainer.AcceptedList.Remove(kvPair.Key); } } catch (Exception ex) { SocketListener.Log.ERR(string.Format("{0}|AliveCheckSockets_ThreadEntry() {1}\r\n{2}", kvPair.Key.ToString(), ex.Message, ex.StackTrace)); continue; } } } }
/// <summary> /// client IP 정보로 client 찾기 /// </summary> /// <param name="endPoint">client IP 정보</param> /// <returns>FACInfo</returns> public static FACInfo FindFACInfo(EndPoint endPoint) { FACInfo info = null; lock (FACContainer.LockThis) { if (!FACContainer.Instance.FacList.TryGetValue(endPoint, out info)) { info = null; } } return(info); }
/// <summary> /// Accept 한 client 추가 (로그인 아님) /// </summary> /// <param name="client">client socket</param> /// <param name="recvEventArgs">등록할 Receive SAEA 객체</param> /// <param name="sendEventArgs">등록할 Send SAEA 객체</param> public static bool AddEx(Socket client, SocketAsyncEventArgs recvEventArgs, SocketAsyncEventArgs sendEventArgs, out string strOutMsg) { strOutMsg = ""; lock (FACContainer.LockThis) { FACInfo fac = new FACInfo(); fac.Socket = client; fac.recvEventArgs = recvEventArgs; fac.sendEventArgs = sendEventArgs; if (FACContainer.Instance.FacList.ContainsKey(client.RemoteEndPoint)) { strOutMsg = "Already Exists FaxAgentCleint. remove old data"; FACContainer.Instance.FacList.Remove(client.RemoteEndPoint); } FACContainer.Instance.FacList.Add(client.RemoteEndPoint, fac); return(true); } }
/// <summary> /// Shutdown -> Close /// </summary> private bool CloseClientSocket(SocketAsyncEventArgs e) { try { SocketListener.Log.MSG(e, "Start Close FaxAgent."); DataHoldingUserToken receiveSendToken = e.UserToken as DataHoldingUserToken; if (receiveSendToken.dataToReceive != null) { receiveSendToken.CreateNewDataHolder(); } // 로그아웃 처리 FACInfo facInfo = FACContainer.FindFACInfo(e); if (facInfo != null) { // DB Logout 처리 if (FACContainer.LoginedList.Count > 0 && facInfo.USER_ID != "") { if (DbModule.Instance.FAS_LogoutAgentClient(facInfo.USER_ID) != Btfax.CommonLib.RESULT.SUCCESS) { SocketListener.Log.WRN(e, "Database Logout process failure"); } else { SocketListener.Log.MSG(e, "Database Logout process success"); } } } // socket close try { e.AcceptSocket.Shutdown(SocketShutdown.Both); } catch { } if (e.AcceptSocket != null) { try { e.AcceptSocket.Close(); e.AcceptSocket = null; } catch { }; } if (facInfo != null) { this.poolOfRecvEventArgs.Push(facInfo.recvEventArgs); this.poolOfSendEventArgs.Push(facInfo.sendEventArgs); } else { this.CreateNewSaeaForRecvSendOne(); SocketListener.Log.MSG(string.Format("CreateNewSaeaForRecvSendOne this.poolOfRecvEventArgs:{0}, this.poolOfSendEventArgs.Push{1}" , this.poolOfRecvEventArgs.Count , this.poolOfSendEventArgs.Count)); } FACContainer.Remove(e); // Accept count 감소 Interlocked.Decrement(ref this.numberOfAcceptedSockets); this.theMaxConnectionsEnforcer.Release(); SocketListener.Log.MSG(e, string.Format("Close FaxAgent success.")); this.DisplayConnectionInfo(); return(true); } catch (Exception ex) { // Accept count 감소 Interlocked.Decrement(ref this.numberOfAcceptedSockets); this.theMaxConnectionsEnforcer.Release(); SocketListener.Log.ERR(string.Format("CloseClientSocket : {0}\r\n{1}", ex.Message, ex.StackTrace)); return(false); } }
private void ProcessSend(SocketAsyncEventArgs sendEventArgs) { int nRemainingCnt = 0; // 이벤트 검사 if (!ValidationCheckSocketAsyncEventArgs("ProcessSend", sendEventArgs)) { return; } DataHoldingUserToken sendToken = sendEventArgs.UserToken as DataHoldingUserToken; nRemainingCnt = sendToken.sendBytesRemainingCount; if (nRemainingCnt <= 0) { SocketListener.Log.TRC(sendEventArgs, string.Format("ProcessSend : Invalid DataHoldingUserToken sendBytesRemainingCount count({0}).", sendToken.sendBytesRemainingCount)); return; } FACInfo facInfo = FACContainer.FindFACInfo(sendEventArgs); if (facInfo == null) { SocketListener.Log.WRN(sendEventArgs, "ProcessSend : Not found FaxAgentInfo."); return; } facInfo.LastResponseTime = DateTime.Now; LOG_LEVEL logLv = LOG_LEVEL.MSG; string packetName = m_Encoding.GetString(sendToken.dataToSend, 34, 5); if (packetName == MessagePacketNameEnum.ALIVE.ToString()) { logLv = LOG_LEVEL.TRC; } else { logLv = LOG_LEVEL.MSG; } // 패킷 로그 SocketListener.Log.LogWrite(logLv, "SEND ", sendEventArgs.AcceptSocket.RemoteEndPoint.ToString(), sendEventArgs.AcceptSocket.Handle.ToInt32(), sendToken.TokenId, sendToken.dataToSend.Length, m_Encoding.GetString(sendToken.dataToSend)); sendToken.sendBytesRemainingCount = sendToken.sendBytesRemainingCount - sendEventArgs.BytesTransferred; sendToken.bytesSentAlreadyCount += sendEventArgs.BytesTransferred; // send async StartSend(sendEventArgs); if (packetName == MessagePacketNameEnum.LOGIN.ToString()) { this.DisplayConnectionInfo(); } }
private void ProcessReceive(SocketAsyncEventArgs recvEventArgs) { DataHoldingUserToken recvToken = recvEventArgs.UserToken as DataHoldingUserToken; // 이벤트 검사 if (!ValidationCheckSocketAsyncEventArgs("ProcessReceive", recvEventArgs)) { recvToken.Reset(); this.CloseClientSocket(recvEventArgs); return; } try { if (recvEventArgs.BytesTransferred == 0) { SocketListener.Log.WRN(recvEventArgs, "RecvEventArgs.BytesTransferred is zero. !!"); recvToken.Reset(); this.CloseClientSocket(recvEventArgs); return; } FACInfo facInfo = FACContainer.FindFACInfo(recvEventArgs); if (facInfo == null) { SocketListener.Log.ERR(recvEventArgs, "Not found facinfo."); recvToken.Reset(); return; } facInfo.LastRequestTime = DateTime.Now; Int32 remainingBytesToProcess = recvEventArgs.BytesTransferred; if (recvToken.receivedPrefixBytesDoneCount < this.socketListenerSettings.ReceivePrefixLength) { /// 공통 전문 첫 컬럼 (전문길이) 읽기 remainingBytesToProcess = prefixHandler.HandlePrefix(recvEventArgs, recvToken, remainingBytesToProcess); if (remainingBytesToProcess == 0) { SocketListener.Log.WRN(recvEventArgs, "RemainingBytesToProcess is zero. !!"); StartReceive(recvEventArgs); return; } } // 전문길이만큼 전문 읽기 bool incomingTcpMessageIsReady = messageHandler.HandleMessage(recvEventArgs, recvToken, remainingBytesToProcess); if (incomingTcpMessageIsReady == true) { SocketAsyncEventArgs sendEventArgs = facInfo.sendEventArgs; if (recvEventArgs == null) { recvToken.Reset(); //CloseClientSocket(recvEventArgs); return; } LOG_LEVEL logLv = LOG_LEVEL.MSG; string packetName = m_Encoding.GetString(recvToken.dataToReceive, 34, 5); if (packetName == MessagePacketNameEnum.ALIVE.ToString()) { logLv = LOG_LEVEL.TRC; } else { logLv = LOG_LEVEL.MSG; } // 패킷 로그 SocketListener.Log.LogWrite(logLv, "RECEIVE ", recvEventArgs.AcceptSocket.RemoteEndPoint.ToString(), recvEventArgs.AcceptSocket.Handle.ToInt32(), recvToken.TokenId, recvToken.dataToReceive.Length, m_Encoding.GetString(recvToken.dataToReceive)); // 응답 전문 보내기 this.SendMessageToClient(sendEventArgs); } else { recvToken.receiveMessageOffset = recvToken.bufferOffsetReceive; recvToken.recPrefixBytesDoneThisOp = 0; } StartReceive(recvEventArgs); } catch (Exception ex) { SocketListener.Log.ERR(recvEventArgs, string.Format("ProcessReceive : {0}", ex.Message)); recvToken.Reset(); } }