예제 #1
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());
            }
        }
예제 #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();
            }
        }
예제 #3
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());
            }
        }
예제 #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());
            }
        }
예제 #5
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());
            }
        }
예제 #6
0
 public void CompletionAction()
 {
     SpinWorker.Dispatch(() =>
     {
         _actionOnCompletion?.Invoke(Buffer);
     });
 }
예제 #7
0
 public void CompletionAction()
 {
     SpinWorker.Dispatch(() =>
     {
         if (_actionOnCompletion != null)
         {
             _actionOnCompletion(Buffer);
         }
     });
 }
예제 #8
0
 private void PostToSpinWorker(Action action)
 {
     if (DispatchWithWorkerThread == true)
     {
         SpinWorker.Work(action);
     }
     else
     {
         SpinWorker.Dispatch(action);
     }
 }
예제 #9
0
        internal void OnReceived(StreamBuffer buffer)
        {
            StreamBuffer buf = new StreamBuffer(buffer);

            SpinWorker.Dispatch(() =>
            {
                if (NetworkEvent_Received != null)
                {
                    NetworkEvent_Received(this, buf);
                }
            });
        }
예제 #10
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;
        }
예제 #11
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;
            }
        }
예제 #12
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());
            }
        }
        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());
            }
        }
예제 #14
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());
            }
        }