public static Frame Decode(ByteBuffer buffer, bool fullBody = true) { Frame frame = new Frame(); frame.RawBuffer = buffer.Array; // Header frame.size = (int)AmqpBitConverter.ReadUInt(buffer); frame.dataOffset = AmqpBitConverter.ReadUByte(buffer); frame.Type = (FrameType)AmqpBitConverter.ReadUByte(buffer); frame.Channel = AmqpBitConverter.ReadUShort(buffer); // skip extended header buffer.Complete(frame.dataOffset * 4 - Frame.HeaderSize); // Command if (buffer.Length > 0) { frame.Command = (Performative)AmqpCodec.CreateAmqpDescribed(buffer); if (fullBody) { frame.Command.DecodeValue(buffer); } } return frame; }
public void WriteFrame(Performative command, bool needReply) { try { Frame frame = new Frame(FrameType.Sasl, 0, command); TransportAsyncCallbackArgs args = new TransportAsyncCallbackArgs(); args.SetBuffer(frame.Buffer); args.CompletedCallback = this.onWriteFrameComplete; args.UserToken = needReply; this.writer.WriteBuffer(args); } catch (Exception exception) { this.HandleException(exception); } }
public void SendCommand(Performative command, ushort channel, Action<object> callback, object state) { Frame frame = new Frame(FrameType.Amqp, channel, command); Utils.Trace(TraceLevel.Frame, "SEND {0}", frame); this.AsyncIO.Writer.WriteBuffer(frame.Buffer, command.PayloadList, callback, state); this.active = true; }
void OnReceiveSessionFrame(Frame frame) { AmqpSession session = null; Performative command = frame.Command; ushort channel = frame.Channel; if (command.DescriptorCode == Begin.Code) { Begin begin = (Begin)command; if (begin.RemoteChannel.HasValue) { // reply to begin lock (this.ThisLock) { if (!this.sessionsByLocalHandle.TryGetObject(begin.RemoteChannel.Value, out session)) { throw new AmqpException(AmqpError.NotFound, SRClient.AmqpChannelNotFound(begin.RemoteChannel.Value)); } session.RemoteChannel = channel; this.sessionsByRemoteHandle.Add(channel, session); } } else { // new begin request AmqpSessionSettings settings = AmqpSessionSettings.Create(begin); settings.RemoteChannel = channel; session = this.SessionFactory.CreateSession(this, settings); this.AddSession(session, channel); } } else { if (!this.sessionsByRemoteHandle.TryGetObject((uint)channel, out session)) { if (frame.Command.DescriptorCode == End.Code || frame.Command.DescriptorCode == Detach.Code) { return; } throw new AmqpException(AmqpError.NotFound, SRClient.AmqpChannelNotFound((uint)channel)); } } session.ProcessFrame(frame); }
void ProcessFrame(Frame frame) { Performative command = frame.Command; Fx.Assert(command != null, "Must have a valid command"); if (command.DescriptorCode == OpenCommand.Code) { this.OnReceiveOpen((Open)frame.Command); } else if (command.DescriptorCode == CloseCommand.Code) { this.OnReceiveClose((Close)frame.Command); } else if (!this.IsClosing()) { this.OnReceiveSessionFrame(frame); } }
void WriteCommand(Performative command) { Frame frame = new Frame(FrameType.Amqp, 0, command); ByteBuffer byteBuffer = ByteBuffer.Wrap(Frame.HeaderSize + command.EncodeSize); frame.Encode(byteBuffer); this.AsyncIO.Writer.WriteBuffer(frame.Buffer, command.PayloadList, null, null); }
public virtual void ProcessFrame(Frame frame) { Performative command = frame.Command; try { if (command.ValueBuffer != null) { // Deferred link frames are decoded here command.DecodeValue(command.ValueBuffer); if (command.ValueBuffer.Length > 0) { command.Payload = command.ValueBuffer.Array; } command.ValueBuffer = null; Utils.Trace(TraceLevel.Frame, "RECV {0}", frame); } if (command.DescriptorCode == Begin.Code) { this.OnReceiveBegin((Begin)command); } else if (command.DescriptorCode == End.Code) { this.OnReceiveEnd((End)command); } else if (command.DescriptorCode == Disposition.Code) { this.OnReceiveDisposition((Disposition)command); } else if (command.DescriptorCode == Flow.Code) { this.OnReceiveFlow((Flow)command); } else { this.OnReceiveLinkFrame(frame); } } catch (Exception exception) { if (Fx.IsFatal(exception)) { throw; } Utils.Trace(TraceLevel.Error, "{0}: Fault with exception: {1}", this, exception); this.TryClose(exception); } }
void OnReceiveLinkFrame(Frame frame) { AmqpLink link = null; Performative command = frame.Command; if (command.DescriptorCode == Attach.Code) { Attach attach = (Attach)command; lock (this.ThisLock) { this.links.TryGetValue(attach.LinkName, out link); } if (link == null) { if (!this.TryCreateRemoteLink(attach, out link)) { return; } } else { lock (this.ThisLock) { link.RemoteHandle = attach.Handle; this.linksByRemoteHandle.Add(attach.Handle.Value, link); } } } else { LinkPerformative linkBody = (LinkPerformative)command; if (!this.linksByRemoteHandle.TryGetObject(linkBody.Handle.Value, out link)) { if (linkBody.DescriptorCode != Detach.Code) { this.TryClose(new AmqpException(AmqpError.UnattachedHandle)); } return; } } try { if (command.DescriptorCode == Transfer.Code) { // pre-process the transfer on the session this.incomingChannel.OnReceiveTransfer(link, (Transfer)command); this.diagnostics.ReceiveTransfer(); } else { link.ProcessFrame(frame); } } catch (AmqpException exception) { this.TryClose(new AmqpException(AmqpError.ErrantLink, exception)); } }
public void ProcessFrame(Frame frame) { Performative command = frame.Command; try { if (command.DescriptorCode == Attach.Code) { this.OnReceiveAttach((Attach)command); } else if (command.DescriptorCode == Detach.Code) { this.OnReceiveDetach((Detach)command); } else if (command.DescriptorCode == Transfer.Code) { // Transfer is called by incoming session directly //this.OnReceiveTransfer((Transfer)command, frame.Payload); } else if (command.DescriptorCode == Flow.Code) { this.OnReceiveFlow((Flow)command); } else { throw new AmqpException(AmqpError.InvalidField, "descriptor-code"); } } catch (AmqpException exception) { this.TryClose(exception); Utils.Trace(TraceLevel.Error, "{0}: Fault with exception: {1}", this, exception); } }