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); }
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); }
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); } }
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); }
/// <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); }
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); } }
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(); } } }