Esempio n. 1
0
        /// <summary>
        /// AegisNetwork 모듈을 초기화합니다.
        /// workerThreadCount와 dispatchThreadCount의 의미는 다음과 같습니다.
        /// -1 : 해당 작업을 AegisTask에서 실행됩니다.
        /// 0 : 해당 작업을 호출하는 쓰레드에서 실행됩니다.
        /// >0 : 정해진 ThreadPool에서 해당 작업이 실행됩니다.
        /// </summary>
        /// <param name="workerThreadCount">백그라운드에서 작업을 처리할 Thread 개수</param>
        /// <param name="dispatchThreadCount">작업결과를 전달할 Thread 개수</param>
        public static void Initialize(Int32 workerThreadCount = -1, Int32 dispatchThreadCount = 1)
        {
            _listNetworkConfig = new List <ConfigNetworkChannel>();
            CustomData         = new CustomData("CustomData");

            SpinWorker.Initialize(workerThreadCount, dispatchThreadCount);
        }
Esempio n. 2
0
        private void SocketEvent_Receive(IAsyncResult ar)
        {
            try
            {
                lock (this)
                {
                    EndPoint remoteEP   = new IPEndPoint(IPAddress.Any, 0);
                    var      socket     = _socket;
                    int      transBytes = socket?.EndReceiveFrom(ar, ref remoteEP) ?? -1;
                    if (transBytes == -1)
                    {
                        return;
                    }

                    byte[] dispatchBuffer = new byte[transBytes];
                    Array.Copy(_receivedBuffer, dispatchBuffer, transBytes);
                    SpinWorker.Dispatch(() =>
                    {
                        EventRead?.Invoke(new IOEventResult(remoteEP, IOEventType.Read, dispatchBuffer, 0, transBytes, 0));
                    });

                    WaitForReceive();
                }
            }
            catch (Exception e)
            {
                Logger.Err(LogMask.Aegis, e.ToString());
                Close();
            }
        }
Esempio n. 3
0
        internal void OnSocket_Accepted()
        {
            try
            {
                if (Activated != null)
                {
                    Activated(this);
                }

                SpinWorker.Dispatch(() =>
                {
                    lock (this)
                    {
                        if (NetworkEvent_Accepted != null)
                        {
                            NetworkEvent_Accepted(this);
                        }

                        _method.WaitForReceive();
                    }
                });
            }
            catch (Exception e)
            {
                Logger.Write(LogType.Err, 1, e.ToString());
            }
        }
Esempio n. 4
0
        internal void OnSocket_Accepted()
        {
            if (PacketValidator == null)
            {
                throw new AegisException(AegisResult.InvalidArgument, "PacketValidator is not set.");
            }

            try
            {
                Activated?.Invoke(this);

                SpinWorker.Dispatch(() =>
                {
                    lock (this)
                    {
                        EventAccept?.Invoke(new IOEventResult(this, IOEventType.Accept, AegisResult.Ok));

                        _method.WaitForReceive();
                    }
                });
            }
            catch (Exception e)
            {
                Logger.Err(LogMask.Aegis, e.ToString());
            }
        }
Esempio n. 5
0
        public void PostQuery(Action <DBCommand> actionOnRead, Action <Exception> actionOnCompletion)
        {
            Exception exception = null;

            _isAsync = true;
            SpinWorker.Work(() =>
            {
                try
                {
                    Query();
                    actionOnRead?.Invoke(this);

                    _isAsync = false;
                    Dispose();
                }
                catch (Exception e)
                {
                    exception = e;
                    _isAsync  = false;
                    Dispose();
                    throw;  //  상위 Exception Handler가 처리하도록 예외를 던진다.
                }
            },
                            () => { actionOnCompletion?.Invoke(exception); });
        }
Esempio n. 6
0
        /// <summary>
        /// 사용중인 리소스를 반환하고 소켓을 종료하여 네트워크 작업을 종료합니다.
        /// 종료처리 후 EventClose가 호출됩니다.
        /// </summary>
        public virtual void Close(int reason = AegisResult.Ok)
        {
            try
            {
                //  작업 중 다른 이벤트가 처리되지 못하도록 Clear까지 lock을 걸어야 한다.
                lock (this)
                {
                    if (Socket == null)
                    {
                        return;
                    }

                    Socket.LingerState = new LingerOption(true, 3);
                    Socket.Close();
                    Socket = null;


                    Inactivated?.Invoke(this);


                    SpinWorker.Dispatch(() =>
                    {
                        EventClose?.Invoke(new IOEventResult(this, IOEventType.Close, reason));
                    });


                    _method.Clear();
                }
            }
            catch (Exception e)
            {
                Logger.Err(LogMask.Aegis, e.ToString());
            }
        }
Esempio n. 7
0
        private void OnSocket_Connect(IAsyncResult ar)
        {
            try
            {
                lock (this)
                {
                    try
                    {
                        if (Socket == null)
                        {
                            return;
                        }

                        Socket.EndConnect(ar);
                    }
                    catch (Exception)
                    {
                        //  Nothing to do.
                    }



                    if (Socket.Connected == true)
                    {
                        if (Activated != null)
                        {
                            Activated(this);
                        }


                        SpinWorker.Dispatch(() =>
                        {
                            if (NetworkEvent_Connected != null)
                            {
                                NetworkEvent_Connected(this, true);
                            }
                        });

                        _method.WaitForReceive();
                    }
                    else
                    {
                        Socket.Close();
                        Socket = null;

                        SpinWorker.Dispatch(() =>
                        {
                            if (NetworkEvent_Connected != null)
                            {
                                NetworkEvent_Connected(this, false);
                            }
                        });
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Write(LogType.Err, 1, e.ToString());
            }
        }
Esempio n. 8
0
 public void CompletionAction()
 {
     SpinWorker.Dispatch(() =>
     {
         _actionOnCompletion?.Invoke(Buffer);
     });
 }
Esempio n. 9
0
        public void PostQuery(Action actionOnRead, Action <Exception> actionOnCompletion)
        {
            Exception exception = null;

            _isAsync = true;
            SpinWorker.Work(() =>
            {
                try
                {
                    Query();
                    if (actionOnRead != null)
                    {
                        actionOnRead();
                    }

                    _isAsync = false;
                    Dispose();
                }
                catch (Exception e)
                {
                    exception = e;
                    _isAsync  = false;
                    Dispose();
                    throw;  //  상위 Exception Handler가 처리하도록 예외를 던진다.
                }
            },
                            () => { actionOnCompletion(exception); });
        }
Esempio n. 10
0
 public void CompletionAction()
 {
     SpinWorker.Dispatch(() =>
     {
         if (_actionOnCompletion != null)
         {
             _actionOnCompletion(Buffer);
         }
     });
 }
Esempio n. 11
0
 private void PostToSpinWorker(Action action)
 {
     if (DispatchWithWorkerThread == true)
     {
         SpinWorker.Work(action);
     }
     else
     {
         SpinWorker.Dispatch(action);
     }
 }
Esempio n. 12
0
        /// <summary>
        /// 사용중인 모든 리소스를 반환하고, AegisNetwork을 종료합니다.
        /// </summary>
        public static void Release()
        {
            SpinWorker.Release();
            StopNetwork();

            if (_mutex != null)
            {
                _mutex.Close();
                _mutex = null;
            }
        }
Esempio n. 13
0
        internal void OnReceived(StreamBuffer buffer)
        {
            StreamBuffer buf = new StreamBuffer(buffer);

            SpinWorker.Dispatch(() =>
            {
                if (NetworkEvent_Received != null)
                {
                    NetworkEvent_Received(this, buf);
                }
            });
        }
Esempio n. 14
0
        private static void TimerThreadRunner()
        {
            MinMaxValue <long>   sleepTime  = new MinMaxValue <long>(0);
            List <IntervalTimer> deprecated = new List <IntervalTimer>();


            while (true)
            {
                if (_threadWait.WaitOne((int)sleepTime.Min) == true)
                {
                    break;
                }


                using (_lock.ReaderLock)
                {
                    deprecated.Clear();
                    sleepTime.Reset(100);

                    foreach (var timer in _queue)
                    {
                        long remainTime = timer.Interval - (_stopwatch.ElapsedMilliseconds - timer._lastCallTime);
                        if (remainTime > 0)
                        {
                            sleepTime.Value = remainTime;
                        }
                        else
                        {
                            timer._lastCallTime = _stopwatch.ElapsedMilliseconds;
                            SpinWorker.Dispatch(timer._action);

                            //  호출횟수 만료
                            if (timer._remainCount != -1 &&
                                --timer._remainCount == 0)
                            {
                                deprecated.Add(timer);
                            }
                        }
                    }
                }

                foreach (var timer in deprecated)
                {
                    timer.Dispose();
                }
            }
            _timerThread = null;
        }
Esempio n. 15
0
        public void Close()
        {
            lock (this)
            {
                if (_socket == null)
                {
                    return;
                }

                EndPoint ep = _endPoint;
                SpinWorker.Dispatch(() =>
                {
                    EventClose?.Invoke(new IOEventResult(ep, IOEventType.Close, 0));
                });

                _socket.Close();
                _socket = null;
            }
        }
Esempio n. 16
0
        public void PostQueryNoReader()
        {
            _isAsync = true;
            SpinWorker.Work(() =>
            {
                try
                {
                    QueryNoReader();

                    _isAsync = false;
                    Dispose();
                }
                catch (Exception)
                {
                    _isAsync = false;
                    Dispose();
                    throw;  //  상위 Exception Handler가 처리하도록 예외를 던진다.
                }
            });
        }
Esempio n. 17
0
        /// <summary>
        /// 사용중인 리소스를 반환하고 소켓을 종료하여 네트워크 작업을 종료합니다.
        /// 종료 처리가 진행되기 이전에 OnClose 함수가 호출됩니다.
        /// </summary>
        public virtual void Close()
        {
            try
            {
                //  작업 중 다른 이벤트가 처리되지 못하도록 Clear까지 lock을 걸어야 한다.
                lock (this)
                {
                    if (Socket == null)
                    {
                        return;
                    }

                    Socket.LingerState = new LingerOption(true, 3);
                    Socket.Close();
                    Socket = null;


                    if (Inactivated != null)
                    {
                        Inactivated(this);
                    }


                    SpinWorker.Dispatch(() =>
                    {
                        if (NetworkEvent_Closed != null)
                        {
                            NetworkEvent_Closed(this);
                        }
                    });


                    _method.Clear();
                }
            }
            catch (Exception e)
            {
                Logger.Write(LogType.Err, 1, e.ToString());
            }
        }
Esempio n. 18
0
        public void PostQueryNoReader(Action <Exception> actionOnCompletion)
        {
            Exception exception = null;

            _isAsync = true;
            SpinWorker.Work(() =>
            {
                try
                {
                    QueryNoReader();

                    _isAsync = false;
                    Dispose();
                }
                catch (Exception e)
                {
                    exception = e;
                    _isAsync  = false;
                    Dispose();
                }
            },
                            () => { actionOnCompletion?.Invoke(exception); });
        }
Esempio n. 19
0
        private void Socket_Connect(IAsyncResult ar)
        {
            try
            {
                lock (this)
                {
                    try
                    {
                        if (Socket == null)
                        {
                            return;
                        }

                        Socket.EndConnect(ar);
                    }
                    catch (Exception)
                    {
                        //  Nothing to do.
                    }


                    Action <int> resultHandler = (ar.AsyncState as Action <int>);
                    if (Socket.Connected == true)
                    {
                        Activated?.Invoke(this);

                        if (resultHandler != null)
                        {
                            resultHandler(AegisResult.Ok);
                        }
                        else
                        {
                            SpinWorker.Dispatch(() =>
                            {
                                EventConnect?.Invoke(new IOEventResult(this, IOEventType.Connect, AegisResult.Ok));
                            });
                        }

                        _method.WaitForReceive();
                    }
                    else
                    {
                        Socket.Close();
                        Socket = null;


                        if (resultHandler != null)
                        {
                            resultHandler(AegisResult.ConnectionFailed);
                        }
                        else
                        {
                            SpinWorker.Dispatch(() =>
                            {
                                EventConnect?.Invoke(new IOEventResult(this, IOEventType.Accept, AegisResult.ConnectionFailed));
                            });
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Err(LogMask.Aegis, e.ToString());
            }
        }
Esempio n. 20
0
        public static void Initialize()
        {
            string[] args = Environment.GetCommandLineArgs();


            //  프레임워크 초기화
            {
                SpinWorker.Initialize();


                _stopRunningEvent = new EventWaitHandle(false, EventResetMode.ManualReset);
                _releaseEvent     = new EventWaitHandle(false, EventResetMode.ManualReset);
                Logger.Info(LogMask.Aegis, "Aegis Framework({0})", AegisVersion.ToString(3));
            }



            AegisTask.Run(() =>
            {
                //  컨텐츠 초기화 (UI 모드)
                if (Environment.UserInteractive)
                {
                    AegisTask.SafeAction(() =>
                    {
                        if (Initialized == null ||
                            Initialized.Invoke(args) == true)
                        {
                            Running?.Invoke();
                        }
                    });

                    AegisTask.SafeAction(() => { Finalizing?.Invoke(CloseReason.Close); });
                }
                //  컨텐츠 초기화 (서비스 모드)
                else
                {
                    ServiceMain.Instance.EventStart = () =>
                    {
                        AegisTask.SafeAction(() =>
                        {
                            if (Initialized == null ||
                                Initialized?.Invoke(System.Environment.GetCommandLineArgs()) == true)
                            {
                                //  Running이 설정된 경우에는 Running이 반환되기를 대기하고, 반환된 후 종료처리 진행
                                if (Running != null)
                                {
                                    (new Thread(() =>
                                    {
                                        AegisTask.SafeAction(() => { Running.Invoke(); });
                                        ServiceMain.Instance.Stop();
                                    })).Start();
                                }
                            }
                        });
                    };
                    ServiceMain.Instance.EventStop = () =>
                    {
                        AegisTask.SafeAction(() => { Finalizing?.Invoke(CloseReason.ServiceStop); });
                    };
                    ServiceMain.Instance.EventShutDown = () =>
                    {
                        AegisTask.SafeAction(() => { Finalizing?.Invoke(CloseReason.ShutDown); });
                    };
                    ServiceMain.Instance.Run();
                }


                _stopRunningEvent.Set();
            });


            AegisTask.Run(() =>
            {
                WaitForRunning();


                //  프레임워크 종료
                Calculate.IntervalTimer.DisposeAll();
                NamedThread.DisposeAll();
                NamedObjectManager.Clear();
                SpinWorker.Release();


                Logger.Info(LogMask.Aegis, "Aegis Framework finalized.");
                Logger.RemoveAll();


                AegisTask.SafeAction(() => { Finalized?.Invoke(); });
                Initialized = null;
                Finalizing  = null;
                Finalized   = null;
                Running     = null;

                _releaseEvent.Set();
            });
        }
Esempio n. 21
0
        private void ProcessContext(HttpListenerContext context)
        {
            String path, rawUrl = context.Request.RawUrl;

            if (rawUrl == "")
            {
                return;
            }


            String[]      splitUrl = rawUrl.Split('?');
            String        rawMessage;
            WebAPIRequest request = null;


            //  Path 가져오기
            path = splitUrl[0].ToLower();
            if (path.Length == 0)
            {
                return;
            }

            if (path.Length > 1 && path[path.Length - 1] == '/')
            {
                path = path.Remove(path.Length - 1);
            }


            //  Query / Message Body 가져오기
            if (context.Request.HttpMethod == "GET")
            {
                if (splitUrl.Length > 1)
                {
                    rawMessage = splitUrl[1];
                    request    = new WebAPIRequest(WebMethodType.Get, rawUrl, path, rawMessage);
                }
                else
                {
                    request = new WebAPIRequest(WebMethodType.Get, rawUrl, path, "");
                }
            }
            if (context.Request.HttpMethod == "POST")
            {
                using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
                {
                    rawMessage = reader.ReadToEnd();
                    request    = new WebAPIRequest(WebMethodType.Post, rawUrl, path, rawMessage);
                }
            }


            //  Routing
            RequestHandler handler;

            if (request == null)
            {
                return;
            }


            using (_lock.ReaderLock)
            {
                if (_routes.TryGetValue(path, out handler) == false)
                {
                    return;
                }
            }


            SpinWorker.Work(() =>
            {
                handler(request, context.Response);
            });
        }
        private void ReceiveComplete(object sender, SocketAsyncEventArgs saea)
        {
            try
            {
                lock (_session)
                {
                    //  transBytes가 0이면 원격지 혹은 네트워크에 의해 연결이 끊긴 상태
                    int transBytes = saea.BytesTransferred;
                    if (transBytes == 0)
                    {
                        _session.Close(AegisResult.ClosedByRemote);
                        return;
                    }


                    _receivedBuffer.Write(transBytes);
                    while (_receivedBuffer.ReadableSize > 0)
                    {
                        //  패킷 하나가 정상적으로 수신되었는지 확인
                        int          packetSize;
                        StreamBuffer tmpBuffer = new StreamBuffer(_receivedBuffer, _receivedBuffer.ReadBytes, _receivedBuffer.ReadableSize);
                        if (_session.PacketValidator == null ||
                            _session.PacketValidator(tmpBuffer, out packetSize) == false)
                        {
                            break;
                        }

                        try
                        {
                            //  수신 이벤트 처리 중 종료 이벤트가 발생한 경우
                            if (_session.Socket == null)
                            {
                                return;
                            }


                            //  수신버퍼에서 제거
                            _receivedBuffer.Read(packetSize);


                            //  수신처리(Dispatch)
                            StreamBuffer dispatchBuffer = new StreamBuffer(tmpBuffer, 0, packetSize);
                            SpinWorker.Dispatch(() =>
                            {
                                if (_responseSelector.Dispatch(dispatchBuffer) == false)
                                {
                                    _session.OnReceived(dispatchBuffer);
                                }
                            });
                        }
                        catch (Exception e)
                        {
                            Logger.Err(LogMask.Aegis, e.ToString());
                        }
                    }


                    //  처리된 패킷을 버퍼에서 제거
                    _receivedBuffer.PopReadBuffer();

                    //  ReceiveBuffer의 안정적인 처리를 위해 작업이 끝난 후에 다시 수신대기
                    WaitForReceive();
                }
            }
            catch (SocketException)
            {
                _session.Close(AegisResult.ClosedByRemote);
            }
            catch (Exception e)
            {
                Logger.Err(LogMask.Aegis, e.ToString());
            }
        }