Ejemplo n.º 1
0
        public Task UnsafeCloseAsync()
        {
            // var promise = new TaskCompletionSource();
            //if (this.Open)
            //{
            //    With.NoException(() => this.Socket.Shutdown(SocketShutdown.Both));
            //}
            With.NoException(() => this.Socket.Dispose());
            if (ReceiveEventArgs != null)
            {
                With.NoException(() => ReceiveEventArgs.Dispose());
                ReceiveEventArgs = null;
            }


            if (this.Open)  //只有有效的连接 才触发连接断开事件
            {
                this.Open = false;
                this.Pipeline.FireChannelInactive();
            }
            //promise.TryComplete();
            //return promise.Task;

            return(Task.CompletedTask);
        }
Ejemplo n.º 2
0
        public Task UnsafeConnectAsync(EndPoint remoteAddress)
        {
            if (Open)
            {
                return(Task.CompletedTask);
            }

            if (ConnectPromise != null)
            {
                throw new InvalidOperationException("connection attempt already made");
            }
            RequestRemoteAddress = remoteAddress;
            var connectEventArgs = new SocketChannelAsyncOperation(this);

            connectEventArgs.RemoteEndPoint = remoteAddress;
            connectEventArgs.Completed     += IO_Completed;
            bool connected = !this.Socket.ConnectAsync(connectEventArgs);

            if (connected)
            {
                ConnectFinish(connectEventArgs);
            }
            else
            {
                var timeout = ConfigContainer.Instance.ConnectTimeoutSecond;//10秒
                ConnectPromise = new TaskCompletionSource(remoteAddress);
                var scheduled = this.EventExecutor.Schedule(() =>
                {
                    var cause = new TimeoutException("connection timed out: " + timeout.ToString());
                    if (ConnectPromise != null && ConnectPromise.TrySetException(cause))
                    {
                        Util.CloseSafe(this);
                    }
                }, TimeSpan.FromSeconds(timeout));

                ConnectPromise.Task.ContinueWith((t, s) =>
                {
                    scheduled?.Cancel();
                    ConnectPromise = null;
                }, null);
                return(ConnectPromise.Task);
                //这里做个超时处理
                //try
                //{
                //    await ConnectPromise.Task.TimeoutAfter(TimeSpan.FromSeconds(timeout));
                //}
                //catch (TimeoutException)
                //{
                //    ConnectPromise.SetException(new TimeoutException("连接超时"));
                //}
                //await ConnectPromise.Task;
            }

            return(Task.CompletedTask);
        }
Ejemplo n.º 3
0
        protected override void Connect0()
        {
            SocketChannelAsyncOperation eventPayload = new SocketChannelAsyncOperation(this, true);

            eventPayload.RemoteEndPoint = RemoteAddress;
            bool connected = this.Socket.ConnectAsync(eventPayload);

            if (connected == false)
            {
                //connected不代表连接失败。。代表不会触发complete事件
                this.FinishConnect(eventPayload);
            }
        }
Ejemplo n.º 4
0
 public override void FinishRead(SocketChannelAsyncOperation operation)
 {
     base.FinishRead(operation);
     if (this.state == StateFlags.Close)
     {
         return;
     }
     if (operation.RemoteEndPoint != null && operation.RemoteEndPoint.ToString() != this.RemoteAddress.ToString())
     {
         this.Socket.Connect(operation.RemoteEndPoint);
         this.FinishConnect(null);
     }
 }
        /// <summary>
        /// 开始读取  (开始接收连接或开始接收数据)
        /// </summary>
        /// <returns></returns>
        public IChannel UnsafeBeginRead()
        {
            //开始接收连接
            //服务端socket启动时增加handler,在channelread中,接收新接收的连接,进行初始化,注册等任务。
            if (IsBeginRead == true)
            {
                return(this);
            }
            IsBeginRead = true;

            AcceptEventArg            = new SocketChannelAsyncOperation(this);
            AcceptEventArg.Completed += AceptOperation_Completed;
            StartAccept(AcceptEventArg);

            return(this);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 开始读取  (开始接收连接或开始接收数据)
        /// </summary>
        /// <returns></returns>
        public IChannel UnsafeBeginRead()
        {
            if (IsBeginRead)
            {
                return(this);
            }
            IsBeginRead = true;

            ReceiveEventArgs            = new SocketChannelAsyncOperation(this);
            ReceiveEventArgs.Completed += IO_Completed;
            //var buffer = new byte[256];
            //ReceiveEventArgs.SetBuffer(buffer, 0, buffer.Length);
            ReceiveEventArgs.SetBuffer(null, 0, 0);
            ReceiveEventArgs.AcceptSocket = this.Socket;
            StartReceive(ReceiveEventArgs);

            return(this);
        }
Ejemplo n.º 7
0
        protected override void Connect0()
        {
            var readOperation = new SocketChannelAsyncOperation(this, false);

            readOperation.RemoteEndPoint = new IPEndPoint(Socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, IPEndPoint.MinPort);
            Boolean willRaiseEvent = this.Socket.ReceiveFromAsync(readOperation);

            if (!willRaiseEvent)
            {
                this.FinishRead(readOperation);
            }
            var ack  = MessageFactory.Create(this.Pipeline.ClientID, this.Pipeline.SessionID, ContractType.HandShake);
            var data = ack.ToByteBuffer().ToArray();
            var e    = WriteOperation;

            e.RemoteEndPoint = this.RemoteAddress;
            e.SetBuffer(data, 0, data.Length);
            Boolean willRaiseSendEvent = this.Socket.SendToAsync(e);

            if (!willRaiseSendEvent)
            {
                this.FinishWrite(e);
            }
        }
Ejemplo n.º 8
0
            public override void FinishRead(SocketChannelAsyncOperation operation)
            {
                Contract.Assert(this.channel.EventLoop.InEventLoop);

                CustTcpServerSocketChannel ch = this.Channel;

                if ((ch.ResetState(StateFlags.ReadScheduled) & StateFlags.Active) == 0)
                {
                    return; // read was signaled as a result of channel closure
                }
                IChannelConfiguration       config      = ch.Configuration;
                IChannelPipeline            pipeline    = ch.Pipeline;
                IRecvByteBufAllocatorHandle allocHandle = this.Channel.Unsafe.RecvBufAllocHandle;

                allocHandle.Reset(config);

                bool      closed    = false;
                Exception exception = null;

                try
                {
                    Socket connectedSocket = null;
                    try
                    {
                        connectedSocket        = operation.AcceptSocket;
                        operation.AcceptSocket = null;
                        operation.Validate();

                        var message = this.PrepareChannel(connectedSocket);

                        connectedSocket = null;

                        ch.ReadPending = false;
                        pipeline.FireChannelRead(message);
                        allocHandle.IncMessagesRead(1);

                        if (!config.AutoRead && !ch.ReadPending)
                        {
                            // ChannelConfig.setAutoRead(false) was called in the meantime.
                            // Completed Accept has to be processed though.
                            return;
                        }

                        while (allocHandle.ContinueReading())
                        {
                            connectedSocket = ch.Socket.Accept();
                            message         = this.PrepareChannel(connectedSocket);

                            connectedSocket = null;
                            ch.ReadPending  = false;
                            pipeline.FireChannelRead(message);
                            allocHandle.IncMessagesRead(1);
                        }
                    }
                    catch (SocketException ex) when(ex.SocketErrorCode == SocketError.OperationAborted || ex.SocketErrorCode == SocketError.InvalidArgument)
                    {
                        closed = true;
                    }
                    catch (SocketException ex) when(ex.SocketErrorCode == SocketError.WouldBlock)
                    {
                    }
                    catch (SocketException ex)
                    {
                        // socket exceptions here are internal to channel's operation and should not go through the pipeline
                        // especially as they have no effect on overall channel's operation
                        Logger.Info("Exception on accept.", ex);
                    }
                    catch (ObjectDisposedException)
                    {
                        closed = true;
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }

                    allocHandle.ReadComplete();
                    pipeline.FireChannelReadComplete();

                    if (exception != null)
                    {
                        // ServerChannel should not be closed even on SocketException because it can often continue
                        // accepting incoming connections. (e.g. too many open files)

                        pipeline.FireExceptionCaught(exception);
                    }

                    if (closed && ch.Open)
                    {
                        this.CloseSafe();
                    }
                }
                finally
                {
                    // Check if there is a readPending which was not processed yet.
                    if (!closed && (ch.ReadPending || config.AutoRead))
                    {
                        ch.DoBeginRead();
                    }
                }
            }