Close() 공개 메소드

public Close ( ) : void
리턴 void
예제 #1
0
파일: Server.cs 프로젝트: sm6uax/plegma
        //------------------------------------------------------------------------------------------------------------------------
        public void Stop(bool CloseAllChannels = false)
        {
            try
            {
                lock (this)
                {
                    //close all channels
                    if (CloseAllChannels)
                    {
                        _Channels.ForEach(c => { try { c.Close("Server stopped"); } catch (Exception ex) { DebugEx.Assert(ex, "Error while closing channel"); } });
                        _Channels.Clear();
                    }

                    //update flag
                    if (!_IsRunning)
                    {
                        return;
                    }
                    else
                    {
                        _IsRunning = false;
                    }

                    //close my socket
                    try
                    {
                        if (sock != null)
                        {
#if NETFX
                            try { sock.Close(); } catch { }
#endif
                            try { sock.Dispose(); } catch { }
                        }
                    }
                    catch (Exception ex)
                    {
                        DebugEx.TraceErrorException(ex);
                    }
                    sock = null;

                    //wait for task finish
#if NETFX
                    PortListener?.Join(1000);
#elif UNIVERSAL
                    PortListener?.Wait(1000);
#endif
                    PortListener = null;
                }
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "YPChannel Server Stop() failed");
            }
        }
예제 #2
0
파일: Server.cs 프로젝트: sm6uax/plegma
        //------------------------------------------------------------------------------------------------------------------------
        void HandleNewConnection(Socket newsocket)
        {
            try
            {
                #region check reconnection throttle
                try
                {
                    //setup socket
                    newsocket.ReceiveTimeout = -1;
                    newsocket.SendTimeout    = 60 * 1000;

#if NETFX
                    var re = newsocket.RemoteEndPoint.GetIPAddress().ToStringInvariant();
#elif UNIVERSAL
                    var re = newsocket.Information.RemoteAddress.ToStringInvariant();
#endif
                    //filtering
                    if (OnNewSocketConnectionFilter != null && OnNewSocketConnectionFilter(this, re) == false)
                    {
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }
                        DebugEx.TraceWarning("Connection from " + re + " closed from filter");
                        return;
                    }

                    if (IsReconnectionThrottleEnabled && re != "127.0.0.1" && re != "localhost") //no reconnection throttle for localhost connections
                    {
                        var rbe = reconnectThrottleBookKeeper.TryGetOrDefault(re);
                        if (rbe == null)
                        {
                            rbe = new ReconnectionBookkeepEntry()
                            {
                                ConnectionTimestamp = DateTime.Now + TimeSpan.FromMilliseconds(100),
                                Connections         = 1,
                            };
                            reconnectThrottleBookKeeper.ForceAdd(re, rbe);
                        }
                        else
                        {
                            if (++rbe.Connections > ReconnectionThrottleAfterConnectionCount)
                            {
                                var elapsed = DateTime.Now - rbe.ConnectionTimestamp;
                                if (elapsed < ReconnectionThrottleTimeout)
                                {
#if NETFX
                                    try { newsocket.Close(); } catch { }
#endif
                                    try { newsocket.Dispose(); } catch { }
                                    DebugEx.TraceWarning("Connection from " + re + " closed due to reconnection throttle (" + elapsed.Seconds + " sec)");
                                    return;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex) { DebugEx.TraceWarning(ex, "YPServer Reconnection throttle exception"); }

                //cleanup old entries
                reconnectThrottleBookKeeper.RemoveWhere(e => DateTime.Now - e.Value.ConnectionTimestamp > ReconnectionThrottleTimeout);
                #endregion

                //start task new connection
                Task.Run(() =>
                {
                    ServerChannel channel = null;
                    string channelKey     = null;

                    Thread.Sleep(MathTools.GetRandomNumber(1, 100));
                    try
                    {
                        //check
#if NETFX
                        if (!newsocket.Connected)
                        {
                            DebugEx.TraceWarning("YPServer newsocket not connected?");
                            try { newsocket.Close(); } catch { }
                            return;
                        }
#endif
                        //create channel
                        var con = ChannelConstructor;
                        channel = con == null ? new ServerChannel(this, Protocols, SupportedChannelSerializationModes, PreferredChannelSerializationModes, newsocket) : con(Protocols, newsocket);
                        if (channel == null)
                        {
                            DebugEx.Assert("Could not create channel");
#if NETFX
                            try { newsocket.Close(); } catch { }
#endif
                            try { newsocket.Dispose(); } catch { }
                            return;
                        }

                        //add to set
                        lock (_Channels)
                        {
                            //generate unique key
                            while (IssuedKeys.ContainsKey(channelKey = MathTools.GenerateRandomAlphaNumericString(64)))
                            {
                                ;
                            }
                            //set on channel
                            channel._ChannelKey = channelKey;
                            //add to lookups
                            _Channels.Add(channel);
                            IssuedKeys.Add(channelKey, channel);
                        }

                        //start task timeout monitor
                        bool setupFinished = false;
                        Task.Run(() =>
                        {
                            try
                            {
                                //wait
                                Thread.Sleep(30000);
                                //check
                                if (!setupFinished)
                                {
                                    DebugEx.TraceLog($"ServerChannel setup timeout ({channel})");
                                    try { channel.Close("ServerChannel setup timeout"); } catch { }
#if NETFX
                                    try { newsocket?.Close(); } catch { }
#endif
                                    try { newsocket?.Dispose(); } catch { }

                                    //remove from lookups
                                    lock (_Channels)
                                    {
                                        if (channel != null)
                                        {
                                            _Channels.Remove(channel);
                                        }
                                        if (channelKey != null)
                                        {
                                            IssuedKeys.Remove(channelKey);
                                        }
                                    }
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                DebugEx.Assert(ex, $"Unhandled exception ({channel})");
#if NETFX
                                try { newsocket?.Close(); } catch { }
#endif
                                try { newsocket?.Dispose(); } catch { }

                                //remove from lookups
                                lock (_Channels)
                                {
                                    if (channel != null)
                                    {
                                        _Channels.Remove(channel);
                                    }
                                    if (channelKey != null)
                                    {
                                        IssuedKeys.Remove(channelKey);
                                    }
                                }
                                return;
                            }
                        });

                        //set serializer
                        channel.MsgPack = MsgPackSerializer;

                        //setup channel socket
                        if (channel.SetupServerSocket() == false)
                        {
#if NETFX
                            try { newsocket?.Close(); } catch { }
#endif
                            try { newsocket?.Dispose(); } catch { }

                            //remove from lookups
                            lock (_Channels)
                            {
                                if (channel != null)
                                {
                                    _Channels.Remove(channel);
                                }
                                if (channelKey != null)
                                {
                                    IssuedKeys.Remove(channelKey);
                                }
                            }
                            return;
                        }

                        //mark setup finish
                        setupFinished = true;

                        //call event
                        OnNewChannel?.Invoke(this, channel);

                        //start heartbeat
                        channel.Start();
                    }
                    catch (Exception ex)
                    {
                        DebugEx.Assert(ex, "YPServer: Failed setting up new connection for " + channel);
#if NETFX
                        try { newsocket.Close(); } catch { }
#endif
                        try { newsocket.Dispose(); } catch { }

                        //remove from lookups
                        lock (_Channels)
                        {
                            if (channel != null)
                            {
                                _Channels.Remove(channel);
                            }
                            if (channelKey != null)
                            {
                                IssuedKeys.Remove(channelKey);
                            }
                        }
                        return;
                    }
                });
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "YPChannel server setup new connection error");
            }
        }
예제 #3
0
파일: Server.cs 프로젝트: sm6uax/plegma
        //------------------------------------------------------------------------------------------------------------------------
        public void Stop(bool CloseAllChannels = false)
        {
            try
            {
                lock (this)
                {
                    //close all channels
                    if (CloseAllChannels)
                    {
                        var channelsToClose = _Channels.ToArray();
                        TaskEx.RunSafe(() =>
                        {
                            var po = new ParallelOptions()
                            {
                                MaxDegreeOfParallelism = 8
                            };

                            Parallel.ForEach(channelsToClose, po, c =>
                            {
                                { try { c.Close("Server stopped"); } catch (Exception ex) { DebugEx.TraceErrorException(ex, "Error while closing channel"); } };
                            });
                        });
                    }

                    //update flag
                    if (!_IsRunning)
                    {
                        return;
                    }
                    else
                    {
                        _IsRunning = false;
                    }

                    //close my socket
                    try
                    {
                        if (sock != null)
                        {
#if NETFX
                            try { sock.Close(); } catch { }
#endif
                            try { sock.Dispose(); } catch { }
                        }
                    }
                    catch (Exception ex)
                    {
                        DebugEx.TraceErrorException(ex);
                    }
                    sock = null;

                    //wait for task finish
#if NETFX
                    PortListener?.Join(1000);
#elif UNIVERSAL
                    PortListener?.Wait(1000);
#endif
                    PortListener = null;
                }
            }
            catch (Exception ex)
            {
                DebugEx.Assert(ex, "YPChannel Server Stop() failed");
            }
        }
예제 #4
0
        //------------------------------------------------------------------------------------------------------------------------
        protected override void onClose(string Message)
        {
            try
            {
                base.onClose(Message);

                //close all
                try
                {
                    if (streamIn != null)
                    {
#if NETFX
                        TaskEx.RunSafe(streamIn.Close, AssertException: false)?.Wait(1000);
#endif
                        TaskEx.RunSafe(streamIn.Dispose, AssertException: false)?.Wait(1000);
                    }
                }
                catch { }

                try
                {
                    if (streamOut != null)
                    {
#if NETFX
                        TaskEx.RunSafe(streamOut.Close, AssertException: false)?.Wait(1000);
#endif
                        TaskEx.RunSafe(streamOut.Dispose, AssertException: false)?.Wait(1000);
                    }
                }
                catch { }

#if NETFX
                try
                {
                    if (netstream != null)
                    {
                        TaskEx.RunSafe(netstream.Close, AssertException: false)?.Wait(1000);
                        TaskEx.RunSafe(netstream.Dispose, AssertException: false)?.Wait(1000);
                    }
                }
                catch { }
#endif
                try
                {
#if NETFX
                    if (_sock?.Connected == true)
                    {
                        TaskEx.RunSafe(() => _sock?.Disconnect(false), AssertException: false)?.Wait(1000);
                    }

                    TaskEx.RunSafe(() => _sock?.Close(3), AssertException: false)?.Wait(5000);
#endif
                    TaskEx.RunSafe(() => _sock?.Dispose(), AssertException: false)?.Wait(1000);
                }
                catch { }

                //null them
                streamIn  = null;
                streamOut = null;
#if NETFX
                netstream = null;
#endif
                _sock = null;
            }
            catch (Exception ex) { DebugEx.Assert(ex, "YPC (" + Name + ") Exception while disconnecting"); }
        }