/// <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> /// 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> /// 로그인 /// </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> /// 지정시간동안 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> /// UserID 로 접속한 client 찾기 /// </summary> /// <param name="e">UserID</param> /// <returns>FACInfo</returns> public static FACInfo FindFACInfo(string userId) { lock (FACContainer.LockThis) { if (FACContainer.Instance.FacMapList.ContainsKey(userId) == false) { return(null); } // 첫번째 항목을 가져온다 return(FACContainer.FindFACInfo(FACContainer.Instance.FacMapList[userId][0])); } }
/// <summary> /// SAEA 객체로 접속한 client 찾기 /// </summary> /// <param name="e">Receive, Send SAEA 객체</param> /// <returns>FACInfo</returns> public static FACInfo FindFACInfo(SocketAsyncEventArgs e) { try { DataHoldingUserToken dToken = e.UserToken as DataHoldingUserToken; if (dToken == null) { return(null); } EndPoint endPoint = dToken.IpEndPt; return(FACContainer.FindFACInfo(endPoint)); } catch { return(null); } ////EndPoint endPoint = e.AcceptSocket.RemoteEndPoint; ////return FACContainer.FindFACInfo(endPoint); ////FACInfo fInfo = null; ////IPEndPoint ep = null; //try //{ // DataHoldingUserToken dToken = e.UserToken as DataHoldingUserToken; // if (dToken != null) // { // ep = dToken.IpEndPt; // } // else // { // AcceptOpUserToken aToken = e.UserToken as AcceptOpUserToken; // ep = aToken.IpEndPt; // } // EndPoint endPoint = ep;//e.AcceptSocket.RemoteEndPoint; // fInfo = FACContainer.FindFACInfo(endPoint); //} //catch //{ // fInfo = null; //} //return fInfo; }
/// <summary> /// 로그아웃 /// </summary> private MessageStream MessageLogout(MessageReader reader, SocketAsyncEventArgs receiveSendEventArgs) { RESULT result = RESULT.EMPTY; /// 등록된 user_id 와 IP endpoint 가 같은지 확인한다. /// 다르다면 중복 로그인으로 로그아웃을 요청한 것이므로 /// 디비 처리를 하지 않는다. string user_id = reader.GetParam(0); EndPoint endPoint = receiveSendEventArgs.AcceptSocket.RemoteEndPoint; EndPoint endPointComp = FACContainer.FindFACInfo(user_id).RemoteEndPoint; if (endPointComp == null) { result = DbModule.Instance.FAS_LogoutAgentClient(reader.GetParam(0)); } else { if (endPoint.ToString() == endPointComp.ToString()) { result = DbModule.Instance.FAS_LogoutAgentClient(reader.GetParam(0)); } else { result = RESULT.SUCCESS; } } /// 성공 실패 처리 if (result == RESULT.SUCCESS) { return(MessageStream.Response(MessagePacketNameEnum.LOGOT, reader.Header, "성공", reader.GetParam(0))); } else { return(MessageStream.Response(MessagePacketNameEnum.LOGOT, reader.Header, false, "로그아웃 중 오류가 발생하였습니다.")); } }
/// <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(); } }
private void ProcessAccept(SocketAsyncEventArgs acceptEventArgs) { // 이벤트 검사 if (!ValidationCheckSocketAsyncEventArgs("ProcessAccept", acceptEventArgs)) { this.StartAccept(); this.HandleBadAccept(acceptEventArgs); return; } // 최대 접속자 수 설정 Int32 max = this.maxSimultaneousClientsThatWereConnected; Int32 numberOfConnectedSockets = Interlocked.Increment(ref this.numberOfAcceptedSockets); if (numberOfConnectedSockets > max) { Interlocked.Increment(ref this.maxSimultaneousClientsThatWereConnected); } // 다음 소켓 이벤트 대기 처리 : acceptEventArgs -> recvEventArgs, sendEventArgs StartAccept(); SocketListener.Log.MSG(acceptEventArgs, string.Format("Start accept processing !! poolOfAcceptEventArgs:{0}, poolOfRecvEventArgs:{1}, poolOfSendEventArgs:{2}" , this.poolOfAcceptEventArgs.Count , this.poolOfRecvEventArgs.Count , this.poolOfSendEventArgs.Count)); try { // Accept 된 Client 로 추가 : acceptEventArgs -> recvEventArgs, sendEventArgs if (this.poolOfRecvEventArgs.Count <= 1 || this.poolOfSendEventArgs.Count <= 1) { this.CreateNewSaeaForRecvSendOne(); } AcceptOpUserToken aToken = acceptEventArgs.UserToken as AcceptOpUserToken; SocketAsyncEventArgs recvEventArgs = null; SocketAsyncEventArgs sendEventArgs = null; while (true) { recvEventArgs = this.poolOfRecvEventArgs.Pop(); sendEventArgs = this.poolOfSendEventArgs.Pop(); if (recvEventArgs.Buffer == null || sendEventArgs.Buffer == null) { DataHoldingUserToken dToken = recvEventArgs.UserToken as DataHoldingUserToken; if (dToken != null) { this.theBufferManager.SetBuffer(dToken.BufferOffsetRecv, recvEventArgs); SocketListener.Log.WRN(string.Format("Receive SocketAsyncEventArgs buffer is null. reset buffer. Reuse later!! token:{0}, token_offset:{1}, recv_offset:{2}", dToken.TokenId, dToken.BufferOffsetRecv, recvEventArgs.Offset)); } dToken = sendEventArgs.UserToken as DataHoldingUserToken; if (dToken != null) { this.theBufferManager.SetBuffer(dToken.BufferOffsetSend, sendEventArgs); SocketListener.Log.WRN(string.Format("Send SocketAsyncEventArgs buffer is null. reset buffer. Reuse later!! token:{0}, token_offset:{1}, send_offset:{2}", dToken.TokenId, dToken.BufferOffsetSend, sendEventArgs.Offset)); } this.poolOfRecvEventArgs.Push(recvEventArgs); this.poolOfSendEventArgs.Push(sendEventArgs); continue; } break; } InitSocketAsyncEventArgs(ref recvEventArgs); InitSocketAsyncEventArgs(ref sendEventArgs); SocketListener.Log.MSG(string.Format("Start accept processing !! SocketAsyncEventArgs buffer offset. recv_offset:{0}, send_offset:{1}", recvEventArgs.Offset, sendEventArgs.Offset)); (recvEventArgs.UserToken as DataHoldingUserToken).CreateSessionId(); (recvEventArgs.UserToken as DataHoldingUserToken).RemoteIp = aToken.RemoteIp; (recvEventArgs.UserToken as DataHoldingUserToken).RemotePort = aToken.RemotePort; (recvEventArgs.UserToken as DataHoldingUserToken).IpEndPt = aToken.IpEndPt; (sendEventArgs.UserToken as DataHoldingUserToken).CreateSessionId(); (sendEventArgs.UserToken as DataHoldingUserToken).RemoteIp = aToken.RemoteIp; (sendEventArgs.UserToken as DataHoldingUserToken).RemotePort = aToken.RemotePort; (sendEventArgs.UserToken as DataHoldingUserToken).IpEndPt = aToken.IpEndPt; recvEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket; //recvEventArgs.SocketError = acceptEventArgs.SocketError; sendEventArgs.AcceptSocket = acceptEventArgs.AcceptSocket; //sendEventArgs.SocketError = sendEventArgs.SocketError; (recvEventArgs.UserToken as DataHoldingUserToken).socketHandleNumber = (Int32)recvEventArgs.AcceptSocket.Handle; (sendEventArgs.UserToken as DataHoldingUserToken).socketHandleNumber = (Int32)sendEventArgs.AcceptSocket.Handle; // 이벤트 반납 aToken.RemoteIp = ""; aToken.RemotePort = 0; aToken.IpEndPt = null; acceptEventArgs.AcceptSocket = null; this.poolOfAcceptEventArgs.Push(acceptEventArgs); string strMsg; FACContainer.AddEx(recvEventArgs.AcceptSocket, recvEventArgs, sendEventArgs, out strMsg); if (!string.IsNullOrEmpty(strMsg)) { SocketListener.Log.WRN(recvEventArgs, string.Format("FACContainer AddEx - {0}!!", strMsg)); } this.DisplayConnectionInfo(); /// Accept 알림 보내기 SendMessageToClient(sendEventArgs, MessagePacketNameEnum.ACCPT); /// 수신 대기 StartReceive(recvEventArgs); } catch (Exception ex) { // REMOVE - KIMCG : 20140827 // Exception 발생시 재귀 호출로인해 Accept pool 에서 이벤트가 빠진다. -> 추후 이벤트 부족으로 작업불가함. // StartAccept(); // HandleBadAccept(acceptEventArgs); // REMOVE - END SocketListener.Log.ERR(string.Format("ProcessAccept - message:{0}\r\nstac_trace:{1}\r\nsource:{2}", ex.Message, ex.StackTrace, ex.Source)); } }