예제 #1
0
파일: Client.cs 프로젝트: vogon/Demotic
        private void OnMessageReceived(Message msg)
        {
            if (_unacked.ContainsKey(msg.AckNumber))
            {
                AckContext req = _unacked[msg.AckNumber];

                if (req.Handler != null)
                {
                    req.Handler(this, new ResponseReceivedEventArgs
                        {
                            Request = req.Request,
                            Response = msg,
                            Context = req.Context
                        }
                    );
                }

                if (msg.OpCode == MessageOpCode.OK || msg.OpCode == MessageOpCode.NG)
                {
                    _unacked.Remove(msg.AckNumber);
                }
            }
            else
            {
                if (msg.AckNumber != 0)
                {
                    Debug.Print("received unsolicited ack for seq = {0}", msg.AckNumber);
                }
            }
        }
예제 #2
0
        public void NegativeAcknowledge()
        {
            Message msg = new Message
            {
                OpCode = MessageOpCode.NG,
                AckNumber = this._ackNumber
            };

            _channel.SendMessage(msg);
        }
예제 #3
0
            public void Submit(Client client)
            {
                Message msg = new Message();

                msg.OpCode = MessageOpCode.DoScript;
                msg.Attributes["when"] = _trigger;
                msg.Attributes["do"] = _body;

                client.SendMessage(msg, null, OnResponseReceived);
            }
예제 #4
0
        public void QuoteObject(DObject obj)
        {
            Message msg = new Message
            {
                OpCode = MessageOpCode.Quote,
                AckNumber = this._ackNumber
            };

            msg.Attributes["object"] = obj;

            _channel.SendMessage(msg);
        }
예제 #5
0
파일: Server.cs 프로젝트: vogon/Demotic
        private static DObject GetObject(Message msg, string attrName)
        {
            if (!msg.Attributes.ContainsKey(attrName)) return null;

            object value = msg.Attributes[attrName];

            if (value is DObject)
            {
                return (DObject)value;
            }
            else
            {
                return null;
            }
        }
예제 #6
0
파일: Server.cs 프로젝트: vogon/Demotic
        private static string GetString(Message msg, string attrName)
        {
            if (!msg.Attributes.ContainsKey(attrName)) return null;

            object value = msg.Attributes[attrName];

            if (value is string)
            {
                return (string)value;
            }
            else if (value is DString)
            {
                return (string)((DString)value);
            }
            else
            {
                return null;
            }
        }
예제 #7
0
        public void SendMessage(Message msg)
        {
            if (msg.SequenceNumber < 0)
            {
                // get next sequence number and put it into msg.
                msg.SequenceNumber = _nextSeq;
                _nextSeq++;
            }
            else if (msg.SequenceNumber >= _nextSeq)
            {
                // if something above this in the stack passes a sequence number
                // in, we can't override its wishes because it might be using
                // the sequence number to correlate requests with responses.
                _nextSeq = msg.SequenceNumber + 1;
            }

            byte[] payload = _format.Encode(msg);

            _xport.SendData(payload);
        }
예제 #8
0
파일: Server.cs 프로젝트: vogon/Demotic
        private void MakeActionAndDispatch(Message msg, MessageChannel channel)
        {
            UserAction request = null;
            RequestContext context = new RequestContext(channel, msg.SequenceNumber);

            if (msg.OpCode == MessageOpCode.GetObject)
            {
                string path = GetString(msg, "path");

                if (path == null) context.NegativeAcknowledge();

                request = new GetObjectAction(context, path);
            }
            else if (msg.OpCode == MessageOpCode.PutObject)
            {
                string path = GetString(msg, "path");
                DObject value = GetObject(msg, "value");

                if (path == null) context.NegativeAcknowledge();
                if (value == null) context.NegativeAcknowledge();

                request = new PutObjectAction(context, path, value);
            }
            else if (msg.OpCode == MessageOpCode.DoScript)
            {
                string trigger = GetString(msg, "when");
                string body = GetString(msg, "do");

                if (trigger == null) context.NegativeAcknowledge();
                if (body == null) context.NegativeAcknowledge();

                request = new DoScriptAction(context, trigger, body);
            }
            else if (msg.OpCode == MessageOpCode.NG ||
                     msg.OpCode == MessageOpCode.OK ||
                     msg.OpCode == MessageOpCode.Quote)
            {
                // drop it on the floor; not expecting these.
                return;
            }
            else
            {
                throw new NotImplementedException();
            }

            Debug.Assert(request != null);
            _worker.Dispatch(request, context);
        }
예제 #9
0
 public MessageToplevelFrame()
 {
     _msg = new Message();
 }
예제 #10
0
        public byte[] Encode(Message msg)
        {
            Bencoder encoder = new Bencoder();

            encoder.StartDictionary();

            encoder.ByteString(TextEncoding.GetBytes(SequenceNumberFieldName))
                   .Integer(msg.SequenceNumber)
                   .ByteString(TextEncoding.GetBytes(AckNumberFieldName))
                   .Integer(msg.AckNumber)
                   .ByteString(TextEncoding.GetBytes(OpCodeFieldName))
                   .Integer((long)msg.OpCode);

            foreach (string k in msg.Attributes.Keys)
            {
                encoder.ByteString(TextEncoding.GetBytes(k));

                object value = msg.Attributes[k];

                if (typeof(long).IsAssignableFrom(value.GetType()))
                {
                    encoder.Integer((long)value);
                }
                else if (value is DNumber)
                {
                    SerializeDNumber(encoder, (DNumber)value);
                }
                else if (value is string)
                {
                    encoder.ByteString(TextEncoding.GetBytes((string)value));
                }
                else if (value is DString)
                {
                    SerializeDString(encoder, (DString)value);
                }
                else if (value is DRecord)
                {
                    SerializeDRecord(encoder, (DRecord)value);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            encoder.FinishDictionary();

            return encoder.Encoded;
        }
예제 #11
0
파일: Client.cs 프로젝트: vogon/Demotic
 public void SendMessage(Message msg, object context, ResponseReceivedHandler responseHandler)
 {
     _unacked.Add(msg.SequenceNumber,
         new AckContext { Request = msg, Context = context, Handler = responseHandler });
     _channel.SendMessage(msg);
 }
예제 #12
0
 private string MessageToDisplayString(Message msg)
 {
     switch (msg.OpCode)
     {
         case MessageOpCode.GetObject:
             return string.Format("get {0}", msg.Attributes["path"].ToString());
         case MessageOpCode.NG:
             return "error";
         case MessageOpCode.OK:
             return "ok";
         case MessageOpCode.PutObject:
             return string.Format("{0} = {1}", msg.Attributes["path"].ToString(),
                 msg.Attributes["value"]);
         case MessageOpCode.Quote:
             return msg.Attributes["object"].ToString();
         default:
             return "???";
     }
 }
예제 #13
0
 private IEnumerable<Inline> MakeResponseView(Message response)
 {
     return new Inline[]
     {
         new LineBreak(),
         new Run("<= " + MessageToDisplayString(response)),
     };
 }
예제 #14
0
 private IEnumerable<Inline> MakeRequestView(Message request)
 {
     return new Inline[]
     {
         new Bold(new Run("=> " + MessageToDisplayString(request))),
     };
 }