private object PreSubscribeRabbit(int topicId, string host, string exchangeString, string queueString, string routingKey, string field) { if (!hostUriMap.TryGetValue(host, out Uri hostUri)) { //{ Scheme = "amqp", UserName = "******", Password = "******", Host = "localhost", Port = 5672 }; //[amqp://][userName:password@]hostName[:portNumber][/virtualHost] UriBuilder b1 = new UriBuilder(host); UriBuilder b2 = new UriBuilder() { Scheme = b1.Scheme == "http" ? "amqp" : b1.Scheme, // FIX: maybe it was http Host = b1.Host ?? "localhost", Port = b1.Port == 80 ? 5672 : b1.Port, // FIX: maybe it was 80 UserName = b1.UserName ?? "guest", Password = b1.Password ?? "guest", Path = b1.Path }; hostUri = b2.Uri; lock (hostUriMap) hostUriMap[host] = hostUri; } RabbitExchange rabbitExchange = new RabbitExchange(exchangeString); RabbitQueue rabbitQueue = new RabbitQueue(queueString); lock (_subMgr) { if (_subMgr.Subscribe(topicId, hostUri, rabbitExchange.Name, routingKey, field)) { return(_subMgr.GetValue(topicId)); // already subscribed } } CancellationTokenSource cts = new CancellationTokenSource(); Task.Run(() => SubscribeRabbit(topicId, hostUri, rabbitExchange, rabbitQueue, routingKey, field, cts.Token)); return(SubscriptionManager.UninitializedValue); }
private void SubscribeRabbit(int topicId, Uri hostUri, RabbitExchange exchange, RabbitQueue queue, string routingKey, string field, CancellationToken cts) { try { if (!_connections.TryGetValue(hostUri, out IConnection connection)) { var factory = new ConnectionFactory() { Uri = hostUri }; connection = factory.CreateConnection(); lock (_connections) _connections[hostUri] = connection; } using (var channel = connection.CreateModel()) { //channel.BasicQos = 100; channel.ExchangeDeclare( exchange.Name, exchange.Type, exchange.Durable, exchange.AutoDelete, exchange.Arguments); string queueName; if (string.IsNullOrWhiteSpace(queue.Name)) { queueName = channel.QueueDeclare().QueueName; } else { queueName = channel.QueueDeclare(queue.Name, queue.Durable, queue.Exclusive, queue.AutoDelete, queue.Arguments); } channel.QueueBind(queue: queueName, exchange: exchange.Name, routingKey: routingKey); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { if (ea.RoutingKey.Equals(routingKey)) { var rtdSubTopic = SubscriptionManager.FormatPath(hostUri, exchange.Name, routingKey); try { var str = Encoding.UTF8.GetString(ea.Body); _subMgr.Set(rtdSubTopic, str); if (str.StartsWith("{")) { var jo = JsonConvert.DeserializeObject <Dictionary <String, String> >(str); foreach (string field_in in jo.Keys) { var rtdTopicString = SubscriptionManager.FormatPath(hostUri, exchange.Name, routingKey, field_in); _subMgr.Set(rtdTopicString, jo[field_in]); } } } catch (Exception e) { _subMgr.Set(rtdSubTopic, e.Message); Logger.Error(e, "SubscribeRabbit.Received"); } } }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); while (!cts.IsCancellationRequested) { Thread.Sleep(1000); } channel.Close(); } } catch (Exception e) { Logger.Error(e, "SubscribeRabbit"); } }