private void ProcessSend(SocketAsyncEventArgs e) { SendingContext sctx = null; try { sctx = (SendingContext)e.UserToken; if (e.SocketError != SocketError.Success) { var err = e.SocketError; ProcessSendFailed(sctx.SendingBatch, RpcErrorCode.SendFailed, new Exception("Send Body Failed: " + err)); Disconnect(e.SocketError); RpcTcpBufferManager.Release(e); e = null; } else { _tracing.InfoFmt("Socket Send {0} Bytes", e.Count); RpcTcpBufferManager.Release(e); e = null; SendPackets(sctx.NextPacket); } } catch (Exception ex) { _tracing.ErrorFmt(ex, "ProcessSend Failed {0}:{1}", e, e.Buffer.Length); Disconnect(ex, "ProcessSend"); } finally { // // 保护,如果出现了异常,则在此处释放 if (e != null) { RpcTcpBufferManager.Release(e); } } }
public RpcTcpSocketConnection(RpcConnectionDirection direction) { _eRecv = RpcTcpBufferManager.FetchReceiveArgs(); if (_eRecv == null) { throw new Exception("Exceed max connections!"); } ((RpcTcpAsyncArgs)_eRecv).Callback = (e) => ProcessReceive(e); _pendingPackets = new Queue <IRpcTcpSendingPacket>(); _direction = direction; _connected = false; _closed = false; _recycling = false; _counter.Connections.Increment(); }
/// <summary> /// 构造函数, 不需要参数 /// </summary> public RpcTcpClientChannel() : base("tcp") { RpcTcpBufferManager.Initialize(); RpcTcpSimplexConnectionManager.Initialize(); _simplexConnections = new Dictionary <ServerUri, RpcTcpSimplexConnection>(); _duplexConnections = new Dictionary <ServerUri, RpcTcpDuplexConnection>(); p_channelSettings = new RpcChannelSettings() { MaxBodySize = 512 * 1024 * 1024, SupportModes = RpcChannelSupportModes.Connection | RpcChannelSupportModes.DuplexConnection, Version = "4.3", Timeout = RpcTcpBufferManager.Configuration.ChannelItem.Timeout, ConcurrentConnection = RpcTcpBufferManager.Configuration.ChannelItem.SimplexConnections, }; RpcTcpTransactionManager.Initialize(); }
/// <summary> /// 构造函数 /// </summary> /// <param name="port">tcp的监听端口</param> public RpcTcpServerChannel(int port) : base("tcp", "tcp://" + ServiceEnvironment.ComputerAddress + ":" + port) { RpcTcpBufferManager.Initialize(); _port = port; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _connections = new Dictionary <ServerUri, RpcTcpServerConnection>(); p_channelSettings = new RpcChannelSettings() { MaxBodySize = 512 * 1024 * 1024, SupportModes = RpcChannelSupportModes.Connection | RpcChannelSupportModes.DuplexConnection, Version = "4.3", Timeout = RpcTcpBufferManager.Configuration.ChannelItem.Timeout, ConcurrentConnection = RpcTcpBufferManager.Configuration.ChannelItem.SimplexConnections, }; _eAccept = RpcTcpBufferManager.FetchAcceptArgs(); ((RpcTcpAsyncArgs)_eAccept).Callback = (e) => ProcessAccept(e); }
/// <summary> /// 发送报文 /// 如果sendFirst == null, 则优先从queue中dequeue /// 否则, 先取出sendFirst, 然后再从queue中取 /// 这是一个回调链,完全靠回调组织起来的,当_sending = 1时,存在一个回调链 /// </summary> /// <param name="sendFirst"></param> private void SendPackets(IRpcTcpSendingPacket sendFirst) { int size; SocketAsyncEventArgs eSend = null; List <IRpcTcpSendingPacket> batch = new List <IRpcTcpSendingPacket>(); // // 阶段1. 获得第一个能够发送的报文 try { // // 先至少放置一个报文进去 if (sendFirst != null) { batch.Add(sendFirst); } else { if (_pendingPackets.Count == 0) { // // 回调链的最终返回,只有当Queue完全清空以后,置空标记位 _sending = 0; return; } else { lock (_syncSend) { batch.Add(_pendingPackets.Dequeue()); } _counter.SendPending.Decrement(); } } // // 获取第一个包的大小, 并估算对缓冲区的大小的需求 size = GetExpectSize(batch[0]); } catch (Exception ex) { // // 在上面的代码块中如果出现异常,则本次发送失败 _tracing.ErrorFmt(ex, "SendPackets 1 failed"); ProcessSendFailed(batch, RpcErrorCode.SendFailed, ex); // // 扔出异常会导致连接断开,所以直接引发下一个调用链 SendPackets(null); return; } // // 阶段2. 获取缓冲区,并写入数据 try { // // 创建缓冲区, 如果过大会建立新缓冲区 eSend = RpcTcpBufferManager.FetchSendArgs(size, _pendingPackets.Count); MemoryStream stream = new MemoryStream(eSend.Buffer, 0, eSend.Buffer.Length, true, true); int bufferRemain = eSend.Buffer.Length; // // 写入第一个报文 TryWriteBuffer(batch[0], stream, bufferRemain); bufferRemain = bufferRemain - (int)stream.Position; // // 尝试向缓冲区内放置能够发送出去的最多的报文 IRpcTcpSendingPacket packet = null; while (true) { if (_pendingPackets.Count > 0) { lock (_syncSend) { if (_pendingPackets.Count > 0) { packet = _pendingPackets.Dequeue(); } } _counter.SendPending.Decrement(); } else { break; } int offsetBefore = (int)stream.Position; if (TryWriteBuffer(packet, stream, bufferRemain)) { batch.Add(packet); packet = null; } else { break; } int offsetAfter = (int)stream.Position; bufferRemain = bufferRemain - (offsetAfter - offsetBefore); } int bufferSize = (int)stream.Position; _counter.SendPerSec.Increment(); _counter.SendTotal.Increment(); _counter.SendMessageTotal.IncrementBy(batch.Count); _counter.SendMessagePerSec.IncrementBy(batch.Count); _counter.SendBytesPerSec.IncrementBy(bufferSize); _counter.SendBytesTotal.IncrementBy(bufferSize); eSend.UserToken = new SendingContext() { NextPacket = packet, SendingBatch = batch, }; if (eSend is RpcTcpAsyncArgs) { ((RpcTcpAsyncArgs)eSend).Callback = delegate(SocketAsyncEventArgs e) { ProcessSend(e); }; } else { eSend.Completed += new EventHandler <SocketAsyncEventArgs>( (sender, e) => ProcessSend(e) ); } eSend.SetBuffer(0, bufferSize); } catch (Exception ex) { // // 无论如何,先交回缓冲区 RpcTcpBufferManager.Release(eSend); // // 在组织缓冲区的代码块中如果出现异常,则本次发送失败,整批失败 _tracing.ErrorFmt(ex, "SendPackets 2 failed"); ProcessSendFailed(batch, RpcErrorCode.SendFailed, ex); // // 扔出异常会导致连接断开,所以直接引发下一个调用链 SendPackets(null); return; } if (!_socket.SendAsync(eSend)) { ProcessSend(eSend); } }
/// <summary> /// 断开连接,这个方法不会抛出异常 /// </summary> /// <param name="err"></param> public void Close(Exception err) { if (_closed) { return; } else { lock (_syncClose) { if (_closed) { return; } else { _closed = true; _connected = false; } } } _counter.Connections.Decrement(); if (_socket.Connected) { _socket.Shutdown(SocketShutdown.Both); } _socket.Close(); _releasing = true; var l = new List <IRpcTcpSendingPacket>(); lock (_syncSend) { while (_pendingPackets.Count > 0) { l.Add(_pendingPackets.Dequeue()); } _pendingPackets.Clear(); } if (l.Count > 0) { _counter.SendPending.IncrementBy(-l.Count); ProcessSendFailed(l, RpcErrorCode.SendFailed, err); } if (_eRecv != null) { // // TODO: 应该有更优雅的实现方式 // 最好 _eRecv有一个opertion的标志位, 如果正在recieve中,就在receive返回后Release(_eRecv),否则在此处release Thread.Sleep(500); RpcTcpBufferManager.Release(_eRecv); } if (err != null) { _counter.CorruptedTransmissions.Increment(); } if (Disconnected != null) { Disconnected(this); } }