private void Initialize(ChannelHandlerContext ctx) { switch (_state) { case 1: return; case 2: return; } _state = 1; // .NET-specific: if (_executor == null) { _executor = new ExecutorService(); } var currentMillis = Convenient.CurrentTimeMillis(); _lastReadTime.Set(currentMillis); _lastWriteTime.Set(currentMillis); if (AllIdleTimeMillis > 0) { _cts = _executor.Schedule(AllIdleTimeoutTask, ctx, AllIdleTimeMillis); } }
/// <summary> /// .NET-specific decoding handler for incoming UDP messages. /// </summary> public override void Read(ChannelHandlerContext ctx, object msg) { var dgram = msg as DatagramPacket; if (dgram == null) { ctx.FireRead(msg); return; } var buf = dgram.Content; var sender = dgram.Sender; var recipient = dgram.Recipient; try { var decoder = new Decoder(_signatureFactory); bool finished = decoder.Decode(ctx, buf, recipient, sender); if (finished) { // prepare finish ctx.FireRead(decoder.PrepareFinish()); } else { Logger.Warn("Did not get the complete packet!"); } } catch (Exception ex) { Logger.Error("Error in UDP decoding.", ex); throw; } }
public DirectResponder(Dispatcher dispatcher, PeerBean peerBeanMaster, ChannelHandlerContext ctx, Message.Message requestMessage) { _dispatcher = dispatcher; _peerBeanMaster = peerBeanMaster; _ctx = ctx; _requestMessage = requestMessage; }
public PipelineSession(IChannel channel, Pipeline pipeline, IEnumerable <IInboundHandler> inboundHandlers, IEnumerable <IOutboundHandler> outboundHandlers) { _channel = channel; _pipeline = pipeline; InboundHandlers = new LinkedList <IInboundHandler>(inboundHandlers); OutboundHandlers = new LinkedList <IOutboundHandler>(outboundHandlers); _ctx = new ChannelHandlerContext(channel, this); }
public PipelineSession(IChannel channel, Pipeline pipeline, IEnumerable<IInboundHandler> inboundHandlers, IEnumerable<IOutboundHandler> outboundHandlers) { _channel = channel; _pipeline = pipeline; InboundHandlers = new LinkedList<IInboundHandler>(inboundHandlers); OutboundHandlers = new LinkedList<IOutboundHandler>(outboundHandlers); _ctx = new ChannelHandlerContext(channel, this); }
public override void ChannelActive(ChannelHandlerContext ctx) { base.ChannelActive(ctx); int current; if ((current = _counter.IncrementAndGet()) > _limit) { ctx.Channel.Close(); Logger.Warn("Dropped connection because {0} > {1} connections active.", current, _limit); } // fireChannelActive // TODO needed? }
public static void RemoveTimeout(ChannelHandlerContext ctx) { if (ctx.Channel.Pipeline.Names.Contains("timeout0")) { ctx.Channel.Pipeline.Remove("timeout0"); } if (ctx.Channel.Pipeline.Names.Contains("timeout1")) { ctx.Channel.Pipeline.Remove("timeout1"); } }
public override void ExceptionCaught(ChannelHandlerContext ctx, Exception cause) { if (_encoder.Message == null) { Logger.Error("Exception in encoding when starting.", cause); Console.WriteLine(cause.StackTrace); } else if (_encoder.Message != null && !_encoder.Message.IsDone) { Logger.Error("Exception in encoding when started.", cause); Console.WriteLine(cause.StackTrace); } }
public bool Decode(ChannelHandlerContext ctx, AlternativeCompositeByteBuf buffer, IPEndPoint recipient, IPEndPoint sender) { Logger.Debug("Decoding of TomP2P starts now. Readable: {0}.", buffer.ReadableBytes); try { long readerBefore = buffer.ReaderIndex; // set the sender of this message for handling timeout var attrInetAddr = ctx.Attr(InetAddressKey); attrInetAddr.Set(sender); if (Message == null) { bool doneHeader = DecodeHeader(buffer, recipient, sender); if (doneHeader) { // store the sender as an attribute var attrPeerAddr = ctx.Attr(PeerAddressKey); attrPeerAddr.Set(Message.Sender); Message.SetIsUdp(ctx.Channel.IsUdp); if (Message.IsFireAndForget() && Message.IsUdp) { TimeoutFactory.RemoveTimeout(ctx); } } else { return false; } } bool donePayload = DecodePayload(buffer); //DecodeSignature(buffer, readerBefore, donePayload); // TODO discardSomeReadBytes -> performance improvement return donePayload; } catch (Exception ex) { ctx.FireExceptionCaught(ex); Console.WriteLine(ex.ToString()); return true; } }
public void Write(ChannelHandlerContext ctx, object msg) { try { AlternativeCompositeByteBuf buf; bool done; var message = msg as Message; if (message != null) { buf = _preferDirect ? _alloc.CompDirectBuffer() : _alloc.CompBuffer(); // null means create signature done = _encoder.Write(buf, message, null); } else { ctx.FireWrite(msg); // TODO ok? Java uses ctx.write() (3x) return; } message = _encoder.Message; // send buffer if (buf.IsReadable) { // sender/recipient information is extracted in MyUdpClient.SendAsync() ctx.FireWrite(buf); if (done) { message.SetDone(true); // we wrote the complete message, reset state _encoder.Reset(); } } else { ctx.FireWrite(Unpooled.EmptyBuffer); } } catch (Exception ex) { ctx.FireExceptionCaught(ex); } }
public override void Read(ChannelHandlerContext ctx, object msg) { // .NET-specific: use a content wrapper for TCP, similar to TomP2PSinglePacketUdp var piece = msg as StreamPiece; if (piece == null) { //ctx.FireRead(msg); return; } var buf = piece.Content; var sender = piece.Sender; var recipient = piece.Recipient; Logger.Debug("{0}: Cumulating TCP stream piece.", this); try { if (_cumulation == null) { _cumulation = AlternativeCompositeByteBuf.CompBuffer(buf); } else { // add to overhead from last TCP packet _cumulation.AddComponent(buf); } Decoding(ctx, sender, recipient); } catch (Exception) { Logger.Error("Error in TCP decoding."); throw; } finally { // If the currently read buffer is read, it can be deallocated. // In case another TCP packet follows, a new buffer is created. if (_cumulation != null && !_cumulation.IsReadable) { _cumulation = null; // Java: no need to discard bytes as this was done in the decoder already } } }
private void Decoding(ChannelHandlerContext ctx, IPEndPoint sender, IPEndPoint receiver) { bool finished = true; bool moreData = true; while (finished && moreData) { finished = _decoder.Decode(ctx, _cumulation, receiver, sender); if (finished) { _lastId = _decoder.Message.MessageId; moreData = _cumulation.ReadableBytes > 0; ctx.FireRead(_decoder.PrepareFinish()); } else { if (_decoder.Message == null) { // Wait for more data. This may happen if we don't get the first // 58 bytes, which is the size of the header. return; } if (_lastId == _decoder.Message.MessageId) { // This ID was the same as the last and the last message already // finished the parsing. So this message is finished as well, although // it may send only partial content. finished = true; moreData = _cumulation.ReadableBytes > 0; ctx.FireRead(_decoder.PrepareFinish()); } else if (_decoder.Message.IsStreaming()) { ctx.FireRead(_decoder.Message); } // arriving here, the next handler must not be called since another // current architecture -> skip rest of handlers // TCP packet needs to be cumulated ctx.SkipRestRead(); } } }
public override void Read(ChannelHandlerContext ctx, object msg) { // Java uses a SimpleChannelInboundHandler that only expects Message objects var responseMessage = msg as Message.Message; if (responseMessage == null) { return; } if (responseMessage.Command == Rpc.Rpc.Commands.Rcon.GetNr() && responseMessage.Type == Message.Message.MessageType.Ok) { Logger.Debug("Successfully set up the reverse connection to peer {0}.", responseMessage.Recipient.PeerId); _tcsRconResponse.SetResult(responseMessage); } else { Logger.Debug("Could not acquire a reverse connection to peer {0}.", responseMessage.Recipient.PeerId); var ex = new TaskFailedException("Could not acquire a reverse connection. Got: " + responseMessage); _tcsRconResponse.SetException(ex); _tcsResponse.SetException(ex); } }
public virtual void ChannelInactive(ChannelHandlerContext ctx) { _isActivated = false; }
private void Initialize(ChannelHandlerContext ctx) { switch (_state) { case 1: return; case 2: return; } _state = 1; // .NET-specific: if (_executor == null) { _executor = new ExecutorService(); } var currentMillis = Convenient.CurrentTimeMillis(); _lastReadTime.Set(currentMillis); _lastWriteTime.Set(currentMillis); _timer = _executor.ScheduleAtFixedRate(Heartbeating, ctx, TimeToHeartBeatMillis, TimeToHeartBeatMillis); }
/// <summary> /// Set the result as soon as the channel is closed. /// </summary> /// <param name="tcs"></param> /// <param name="result"></param> /// <param name="ctx"></param> public static void ResponseLater(this TaskCompletionSource<Message.Message> tcs, Message.Message result, ChannelHandlerContext ctx) { ctx.Channel.Closed += channel => tcs.SetResult(result); }
public override void UserEventTriggered(ChannelHandlerContext ctx, object evt) { if (evt is IdleStateHandlerTomP2P) { Logger.Warn("Channel timeout for channel {0} {1}.", _name, ctx.Channel); PeerAddress recipient; if (_tcsResponse != null) { // client-side var requestMessage = (Message.Message)_tcsResponse.Task.AsyncState; Logger.Warn("Request status is {0}.", requestMessage); ctx.Channel.Closed += channel => _tcsResponse.SetException( new TaskFailedException(String.Format("{0} is idle: {1}.", ctx.Channel, evt))); ctx.FireTimeout(); ctx.Channel.Close(); recipient = requestMessage.Recipient; } else { // server-side // .NET-specific: // Don't close the channel, as this would close all service loops on a server. // instead, set the session to be timed out. ctx.FireTimeout(); // check if we have set an attribute at least // (if we have already decoded the header) var attrPeerAddr = ctx.Attr(Decoder.PeerAddressKey); recipient = attrPeerAddr.Get(); } if (_peerStatusListeners == null) { return; } var socketAddr = ctx.Channel.RemoteEndPoint; if (socketAddr == null) { var attrInetAddr = ctx.Attr(Decoder.InetAddressKey); socketAddr = attrInetAddr.Get(); } lock (_peerStatusListeners) { foreach (var listener in _peerStatusListeners) { if (recipient != null) { listener.PeerFailed(recipient, new PeerException(PeerException.AbortCauseEnum.Timeout, "Timeout!")); } else { if (socketAddr != null) { listener.PeerFailed(new PeerAddress(Number160.Zero, socketAddr.Address), new PeerException(PeerException.AbortCauseEnum.Timeout, "Timeout!")); } else { Logger.Warn("Cannot determine the sender's address."); } } } } } }
public override void Write(ChannelHandlerContext ctx, object msg) { ctx.Channel.WriteCompleted += channel => _lastWriteTime.Set(Convenient.CurrentTimeMillis()); //ctx.FireWrite(msg); // TODO needed? }
/// <summary> /// Responds within a session. Keeps the connection open if told to do so. /// Connection is only kept alive for TCP content. /// </summary> /// <param name="ctx">The channel context.</param> /// <param name="responseMessage">The response message to send.</param> internal void Respond(ChannelHandlerContext ctx, Message.Message responseMessage) { // TODO if/else can be tied together if (ctx.Channel is IUdpChannel) { // Check, if channel is still open. If not, then do not send anything // because this will cause an exception that will be logged. var channel = ctx.Channel as IUdpChannel; if (!channel.IsOpen) { Logger.Debug("Channel UDP is not open. Do not reply {0}.", responseMessage); return; } Logger.Debug("Response UDP message {0}.", responseMessage); } else if (ctx.Channel is ITcpChannel) { // Check, if channel is still open. If not, then do not send anything // because this will cause an exception that will be logged. var channel = ctx.Channel as ITcpChannel; if (!channel.IsOpen) { Logger.Debug("Channel TCP is not open. Do not reply {0}.", responseMessage); return; } Logger.Debug("Response TCP message {0} to {1}.", responseMessage, "TODO"); // TODO find way to log TCP remoteEndpoint } ctx.FireRead(responseMessage); }
public override void ExceptionCaught(ChannelHandlerContext ctx, Exception cause) { Logger.Debug("Error originating from {0}. Cause: {1}", _message, cause); if (_tcsResponse.Task.IsCompleted) { Logger.Warn("Got exception, but ignored it. (Task completed.): {0}.", _tcsResponse.Task.Exception); } else { Logger.Debug("Exception caught, but handled properly: {0}.", cause.Message); var pe = cause as PeerException; if (pe != null) { if (pe.AbortCause != PeerException.AbortCauseEnum.UserAbort) { // do not force if we ran into a timeout, the peer may be busy lock (PeerBean.PeerStatusListeners) { foreach (IPeerStatusListener listener in PeerBean.PeerStatusListeners) { listener.PeerFailed(_message.Recipient, pe); } } Logger.Debug("Removed from map. Cause: {0}. Message: {1}.", pe, _message); } else { Logger.Warn("Error in request.", cause); } } else { lock (PeerBean.PeerStatusListeners) { foreach (IPeerStatusListener listener in PeerBean.PeerStatusListeners) { listener.PeerFailed(_message.Recipient, new PeerException(cause)); } } } } Logger.Debug("Report failure: ", cause); _tcsResponse.SetException(cause); // TODO channel not already closed in Sender? ctx.Close(); // TODO used? }
//.NET-specific: use channel inactivation instead of close public override void ChannelInactive(ChannelHandlerContext ctx) { _counterCurrent.Decrement(); }
public void Write(ChannelHandlerContext ctx, object msg) { // nothing to do }
public virtual void ExceptionCaught(ChannelHandlerContext ctx, Exception cause) { // do nothing by default // can be overridden }
//.NET-specific: use channel activation instead of connection public override void ChannelActive(ChannelHandlerContext ctx) { _counterCurrent.IncrementAndGet(); _counterTotal.IncrementAndGet(); }
public virtual void HandlerRemoved(ChannelHandlerContext ctx) { // do nothing by default // can be overridden }
public virtual void ChannelActive(ChannelHandlerContext ctx) { _isActivated = true; }
/*public override void HandlerAdded(ChannelHandlerContext ctx) { if (ctx.Channel.IsActive) { Initialize(ctx); } } public override void HandlerRemoved(ChannelHandlerContext ctx) { Destroy(); }*/ public override void ChannelActive(ChannelHandlerContext ctx) { base.ChannelActive(ctx); Initialize(ctx); }
public override void ChannelInactive(ChannelHandlerContext ctx) { _counter.Decrement(); // fireChannelInactive // TODO needed? }
public override void ChannelInactive(ChannelHandlerContext ctx) { base.ChannelInactive(ctx); Destroy(); }
public override void Read(ChannelHandlerContext ctx, object msg) { // server-side: // message comes (over network) from sender // -> correct DispatchHandler handles response // Java uses a SimpleChannelInboundHandler that only expects Message objects var requestMessage = msg as Message.Message; if (requestMessage == null) { return; } Logger.Debug("Received request message {0} from channel {1}.", requestMessage, ctx.Channel); if (requestMessage.Version != _p2PId) { Logger.Error("Wrong version. We are looking for {0}, but we got {1}. Received: {2}.", _p2PId, requestMessage.Version, requestMessage); ctx.Close(); // TODO used? lock (_peerBeanMaster.PeerStatusListeners) { foreach (IPeerStatusListener listener in _peerBeanMaster.PeerStatusListeners) { listener.PeerFailed(requestMessage.Sender, new PeerException(PeerException.AbortCauseEnum.PeerError, "Wrong P2P version.")); } } return; } if (!requestMessage.IsRequest()) { Logger.Debug("Handing request message to the next handler. {0}", requestMessage); ctx.FireRead(msg); return; } IResponder responder = new DirectResponder(this, _peerBeanMaster, ctx, requestMessage); DispatchHandler myHandler = AssociatedHandler(requestMessage); if (myHandler != null) { bool isUdp = ctx.Channel.IsUdp; bool isRelay = requestMessage.Sender.IsRelayed; if (!isRelay && requestMessage.PeerSocketAddresses.Count != 0) { PeerAddress sender = requestMessage.Sender.ChangePeerSocketAddresses(requestMessage.PeerSocketAddresses); requestMessage.SetSender(sender); } Logger.Debug("About to respond to request message {0}.", requestMessage); // handle the request message PeerConnection peerConnection = null; if (!isUdp) { var tcpChannel = ctx.Channel as ITcpChannel; peerConnection = new PeerConnection(requestMessage.Sender, tcpChannel, _heartBeatMillis); } myHandler.ForwardMessage(requestMessage, peerConnection, responder); } else { // do better error handling // if a handler is not present at all, print a warning if (_ioHandlers.Count == 0) { Logger.Debug("No handler found for request message {0}. This peer has probably been shut down.", requestMessage); } else { var knownCommands = KnownCommands(); if (knownCommands.Contains(Convert.ToInt32(requestMessage.Command))) { var sb = new StringBuilder(); foreach (int cmd in knownCommands) { sb.Append((Rpc.Rpc.Commands) cmd + "; "); } Logger.Warn("No handler found for request message {0}. Is the RPC command {1} registered? Found registered: {2}.", requestMessage, (Rpc.Rpc.Commands) requestMessage.Command, sb); } else { Logger.Debug("No handler found for request message {0}. This peer has probably been partially shut down.", requestMessage); } } // return response that states that no handler was found var responseMessage = DispatchHandler.CreateResponseMessage(requestMessage, Message.Message.MessageType.UnknownId, _peerBeanMaster.ServerPeerAddress); Respond(ctx, responseMessage); } }
public override void Read(ChannelHandlerContext ctx, object msg) { _lastReadTime.Set(Convenient.CurrentTimeMillis()); ctx.FireRead(msg); }