Пример #1
0
        public void SerializeMessage(IMessageEnvelope<object> message, IModel model, out IBasicProperties headers, out byte[] body, out string routingKey)
        {
            Stream stream = Serializer.Serialize(message);

            var messageBuilder = new MapMessageBuilder(model);
            messageBuilder.Headers[MessageTypeHeader] = message.GetType().GetGenericArguments()[0].AssemblyQualifiedName;
            headers = (IBasicProperties)messageBuilder.GetContentHeader();

            routingKey = message.Message.GetType().ToRoutingKey();

            body = new byte[stream.Length];
            stream.Read(body, 0, body.Length);
        }
Пример #2
0
        /// <summary>
        /// Default SendMessage should provide performance statistics. Default SendMessage should be <generic/> and be reused.
        /// </summary>
        /// <param name="sourceAddress"></param>
        /// <param name="destAddress"></param>
        /// <param name="op"></param>
        /// <param name="parameters"></param>
        /// <param name="correlationID"></param>
        /// <param name="retVal"></param>
        /// <returns></returns>
        public bool SendMessageImpl( RequestData req )
        {
            try
            {
                MapMessageBuilder builder = new MapMessageBuilder ( this.OutboundChannel );

                #region copy dictionary to headers
                //there is no other way than
                if (req.Data != null)
                    foreach (DictionaryEntry entry in req.Data)
                    {
                        builder.Headers.Add ( (string)entry.Key, entry.Value );
                    }

                //map response
                if (req.Response != null)
                {
                    var parameters = req.Response.Serialize ();
                    if (parameters != null)
                        foreach (DictionaryEntry entry in parameters)
                        {
                            builder.Headers.Add ( (string)entry.Key, entry.Value );
                        }
                }
                #endregion

                //write body
                if(req.Body !=  null)
                    builder.RawWrite(Encoding.UTF8.GetBytes(req.Body));

                //who is publishing - it can be used to determine return route
                builder.Properties.AppId = req.SourceAddress;

                //each message has id for traceability
                builder.Properties.MessageId = Guid.NewGuid ().ToString ();

                //this cid will be used for response
                if (!string.IsNullOrEmpty ( req.CorrelationId))
                    builder.Properties.CorrelationId = req.CorrelationId;

                //what message we want to send
                builder.Headers["op"] = req.Op;

                //time of sending
                builder.Headers["sent"] = DateTime.Now.ToString ( "o" );

                //timeout; will help second party to cancel reposnse thus limitting traffic
                builder.Headers["timeout"] = 0;

                bool confirmed;

                //have to block because it is concurent access to this resource
                lock (this.OutboundChannel)
                {
                    //publish to topic exchange where routin key=destination process address, mandatory=true
                    this.OutboundChannel.BasicPublish ( this.Exchange, req.DestAddress, true, builder.Properties, RMQBus.GetBodyBytes(req.Body) );

                    //sometimes it blocks, maybe I should use timeout and resend? if the second party gets message second time then it should send back the same response
                    confirmed = this.OutboundChannel.WaitForConfirms ();
                }

                if (confirmed)
                    Tracer.TraceEvent ( System.Diagnostics.TraceEventType.Verbose, 0, "[{0}] op '{1}' dest. {2} value {3} cid {4}", this, req.Op, req.DestAddress, req.Response, req.CorrelationId );
                else
                    Tracer.TraceEvent ( System.Diagnostics.TraceEventType.Error, 0, "[{0}] not confirmed op '{1}' dest. {2} value {3} cid {4}", this, req.Op, req.DestAddress, req.Response, req.CorrelationId );

                return confirmed;
            }
            catch (Exception ex)
            {
                Tracer.TraceEvent ( System.Diagnostics.TraceEventType.Error, 0, "{0} send message exception {1}", req.SourceAddress, ex );
                return false;
            }
        }
Пример #3
0
        public static int Main(string[] args)
        {
            bool persistMode = false;

            int optionIndex = 0;
            while (optionIndex < args.Length) {
                if (args[optionIndex] == "/persist") {
                    persistMode = true;
                } else {
                    break;
                }
                optionIndex++;
            }

            if (((args.Length - optionIndex) < 1) ||
                (((args.Length - optionIndex - 1) % 2) == 1))
                {
                    Console.Error.WriteLine("Usage: SendMap [<option> ...] <exchange-uri> [[<key> <value>] ...]");
                    Console.Error.WriteLine("RabbitMQ .NET client version "+typeof(IModel).Assembly.GetName().Version.ToString());
                    Console.Error.WriteLine("Exchange-URI: amqp://host[:port]/exchange[/routingkey][?type=exchangetype]");
                    Console.Error.WriteLine("Keys must start with '+' or with '-'. Those starting with '+' are placed in");
                    Console.Error.WriteLine("the body of the message, and those starting with '-' are placed in the headers.");
                    Console.Error.WriteLine("Values must start with a single character typecode and a colon.");
                    Console.Error.WriteLine("Supported typecodes are:");
                    Console.Error.WriteLine(" S - string/byte array");
                    Console.Error.WriteLine(" x - byte array (base-64)");
                    Console.Error.WriteLine(" t - boolean");
                    Console.Error.WriteLine(" i - 32-bit integer");
                    Console.Error.WriteLine(" d - double-precision float");
                    Console.Error.WriteLine(" D - fixed-point decimal");
                    Console.Error.WriteLine("Note that some types are valid only in the body of a message, and some are");
                    Console.Error.WriteLine("valid only in the headers.");
                    Console.Error.WriteLine("The exchange \"amq.default\" is an alias for the default (\"\") AMQP exchange,");
                    Console.Error.WriteLine("introduced so that the default exchange can be addressed via URI syntax.");
                    Console.Error.WriteLine("Available options:");
                    Console.Error.WriteLine("  /persist     send message in 'persistent' mode");
                    return 2;
                }

            Uri uri = new Uri(args[optionIndex++]);
            string exchange = uri.Segments[1].TrimEnd(new char[] { '/' });
            string exchangeType = uri.Query.StartsWith("?type=") ? uri.Query.Substring(6) : null;
            string routingKey = uri.Segments.Length > 2 ? uri.Segments[2] : "";

            if (exchange == "amq.default") {
                exchange = "";
            }

            ConnectionFactory cf = new ConnectionFactory();
            cf.Endpoint = new AmqpTcpEndpoint(uri);

            using (IConnection conn = cf.CreateConnection())
                {
                    using (IModel ch = conn.CreateModel()) {

                        if (exchangeType != null) {
                            ch.ExchangeDeclare(exchange, exchangeType);
                        }

                        IMapMessageBuilder b = new MapMessageBuilder(ch);
                        while ((optionIndex + 1) < args.Length) {
                            string keyAndDiscriminator = args[optionIndex++];
                            string valueAndType = args[optionIndex++];

                            if (keyAndDiscriminator.Length < 1) {
                                Console.Error.WriteLine("Invalid key: '{0}'", keyAndDiscriminator);
                                return 2;
                            }
                            string key = keyAndDiscriminator.Substring(1);
                            char discriminator = keyAndDiscriminator[0];

                            IDictionary target;
                            switch (discriminator) {
                              case '-':
                                  target = b.Headers;
                                  break;
                              case '+':
                                  target = b.Body;
                                  break;
                              default:
                                  Console.Error.WriteLine("Invalid key: '{0}'",
                                                          keyAndDiscriminator);
                                  return 2;
                            }

                            if (valueAndType.Length < 2 || valueAndType[1] != ':') {
                                Console.Error.WriteLine("Invalid value: '{0}'", valueAndType);
                                return 2;
                            }
                            string valueStr = valueAndType.Substring(2);
                            char typeCode = valueAndType[0];

                            object value;
                            switch (typeCode) {
                              case 'S':
                                  value = valueStr;
                                  break;
                              case 'x':
                                  value = new BinaryTableValue(Convert.FromBase64String(valueStr));
                                  break;
                              case 't':
                                  value = (valueStr.ToLower() == "true" ||
                                           valueStr.ToLower() == "yes" ||
                                           valueStr.ToLower() == "on" ||
                                           valueStr == "1");
                                  break;
                              case 'i':
                                  value = int.Parse(valueStr);
                                  break;
                              case 'd':
                                  value = double.Parse(valueStr);
                                  break;
                              case 'D':
                                  value = decimal.Parse(valueStr);
                                  break;
                              default:
                                  Console.Error.WriteLine("Invalid type code: '{0}'", typeCode);
                                  return 2;
                            }

                            target[key] = value;
                        }
                        if (persistMode) {
                            ((IBasicProperties) b.GetContentHeader()).DeliveryMode = 2;
                        }
                        ch.BasicPublish(exchange,
                                        routingKey,
                                        (IBasicProperties) b.GetContentHeader(),
                                        b.GetContentBody());
                        return 0;
                    }
                }
        }