I am executing below code successfully without any errors but when I am executing list_queue command it gives me no queue. Dont know where the problem is.
The below code is not giving error at all. My machine is windows 7 64x, installed AMPQ runtime 64bit and using 32x RabbitMq server v.2.8.1 .
private void createExchange(string message)
{
var queName = Convert.ToString(ConfigurationManager.AppSettings["clientQueue"]);
var exchangeName = Convert.ToString(ConfigurationManager.AppSettings["clientExchange"]);
var hostName = Convert.ToString(ConfigurationManager.AppSettings["host"]);
_logger.Info("entered in create exchange");
_logger.Info("queName: " + queName);
_logger.Info("exchangeName: " + exchangeName);
_logger.Info("hostName: " + hostName);
try
{
var connectionFactory = new ConnectionFactory();
connectionFactory.HostName = "localhost";
connectionFactory.UserName = "user1";
connectionFactory.Password = "userpassword";
using (IConnection connection =
connectionFactory.CreateConnection())
{
_logger.Info("Conncection created");
using (IModel model = connection.CreateModel())
{
_logger.Info("Model is created");
model.ExchangeDeclare(exchangeName, ExchangeType.Fanout, true);
model.QueueDeclare(queName, true, true, false, null);
model.QueueBind(queName, exchangeName, "", new Dictionary<string, object>());
IBasicProperties basicProperties = model.CreateBasicProperties();
model.BasicPublish(exchangeName, "", false, false,
basicProperties, Encoding.UTF8.GetBytes(message));
_logger.Info("message: " + message);
_logger.Info("message published");
}
}
}
catch(Exception ex)
{
_logger.Info("Error in create exchange");
_logger.Info("InnerException:" + ex.InnerException);
_logger.Info("Message:" + ex.Message);
_logger.Info("StackTrace:" + ex.StackTrace);
}
}
It appears as though you are declaring an 'exclusive' queue. Exclusive queues are exclusive to the connection and as such cannot be operated upon (including being listed) from another connection.
Try
Model.QueueDeclare(queName, true, **false**, false, null)
If you want to be able to list it or do anything else with if from another connection.
Related
I'm developing WPF application to listen to queue in RabbitMQ and do some work in the method CaptureDataFromMessage() when consume message from RMQ queue.
To keep listening RabbitMQ queue, the application using the while loop.
When application starts, I check rabbitMQ connection[CheckRabbitMQStatus()] and if the connection opens then the application will start to listen to the queue, else error message will display in txtOutput(display notification area).
When there is no internet or exception occur while application open & listening to the RabbitMQ queue then I need to provide informative messages to txtOutput. I was trying to check using a connection.IsOpen inside the while loop, even though there is no connection, but it provides true.
So my effort wasn't a success, [but the application working fine & connects itself when an internet connection is back and consuming messages]
1. Please suggest to me how to identify connection lost & connection establish again event to display in txtOutput while application running.
2. Is it OK to use thread inside message receiver method.
This is my code.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
if (CheckRabbitMQStatus())
{
Thread _threadHandleMessage;
_threadHandleMessage = new Thread(() =>
{
QueueListener();
});
_threadHandleMessage.Start();
}
}
private ConnectionFactory CreateConnectionFactory()
{
#region rabbitMQ Configurtions
string HOSTNAME = "RabbitMQServer";
string USERNAME = "RabbitMQUsername";
string RabbitMQPassword = "RabbitMQPassword";
string VHOST = "RabbitMQVHost";
#endregion
return new ConnectionFactory() { HostName = HOSTNAME, UserName = USERNAME, Password = DecryptRabbitMQPassword, VirtualHost = VHOST };
}
private void QueueListener()
{
try
{
string QueueName = "RabbitMQQueueName";
var factory = CreateConnectionFactory();
using (var connection = factory.CreateConnection())
{
if (connection.IsOpen)
{
this.Dispatcher.Invoke(() =>
{
txtOutput.Text = (string.IsNullOrEmpty(txtOutput.Text) ? "" : txtOutput.Text + "\n") + "[" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + "]" + " Application has started.";
});
}
else
{
this.Dispatcher.Invoke(() =>
{
txtOutput.Text = (string.IsNullOrEmpty(txtOutput.Text) ? "" : txtOutput.Text + "\n") + "[" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + "]" + " Application has stopped due to connection failure.";
});
}
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: QueueName,
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
var consumer = new EventingBasicConsumer(channel);
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
channel.BasicConsume(queue: QueueName,
autoAck: false,
consumer: consumer);
HandleMessage handleMessage = new HandleMessage(this.Dispatcher, txtOutput);
Thread _threadPrintMessage;
consumer.Received += (model, ea) =>
{
_threadPrintMessage = new Thread(() =>
{
handleMessage.CaptureDataFromMessage(ea.Body);
});
_threadPrintMessage.Start();
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
while (true)
{
if (connection.IsOpen)
{
// I tried to capture netwok availability from here & else part
// But even there is no internet connection in the computer or queue deleted after connection open, still connection states as OPEN
}
else
{
//
}
}
}
}
}
catch (Exception ex)
{
log.Error(ex);
this.Dispatcher.Invoke(() =>
{
txtOutput.Text = (string.IsNullOrEmpty(txtOutput.Text) ? "" : txtOutput.Text + "\n") + "[" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + "]" + " Error has occured while processing.";
});
}
}
private bool CheckRabbitMQStatus()
{
var factory = CreateConnectionFactory();
IConnection conn = null;
try
{
conn = factory.CreateConnection();
conn.Close();
conn.Dispose();
return true;
}
catch (Exception ex)
{
log.Error(ex);
string mesage ="";
if (ex.Message == "None of the specified endpoints were reachable")
{
mesage = " Application has not started due to connection failure.";
}
else {
mesage = " Application has not started due to a failure.";
}
this.Dispatcher.Invoke(() =>
{
txtOutput.Text = (string.IsNullOrEmpty(txtOutput.Text) ? "" : txtOutput.Text + "\n") + "[" + DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss") + "]" + mesage;
});
return false;
}
}
}
}
Currently am implementing the code for sending a reply email using the Exchange Web service and C#. While debugging the same I come across this exception.
#Exception
Microsoft.Exchange.WebServices.Data.ServiceObjectPropertyException
HResult=0x80131500
Message=You must load or assign this property before you can read its value.
Source=Microsoft.Exchange.WebServices
StackTrace:
at Microsoft.Exchange.WebServices.Data.PropertyBag.get_Item(PropertyDefinition propertyDefinition)
at Microsoft.Exchange.WebServices.Data.Item.get_Body()
at DataLoadLibrary.DataLoad.Email.TestPortRequestOauthBased.startDataload() in C:\Users\aadityaradhakrishnan\Development\IPACT\ROB\ipact-rob\DataLoadLibrary\DataLoad\Email\TestPortRequestOauthBased.cs:line 113
at TestPortEmailReader.Program.<Main>d__8.MoveNext() in C:\Path\TestPortEmailReader\Program.cs:line 87
This exception was originally thrown at this call stack:
[External Code]
DataLoadLibrary.DataLoad.Email.TestPortRequestOauthBased.startDataload() in TestPortRequestOauthBased.cs
TestPortEmailReader.Program.Main(string[]) in Program.cs
#Implementation
public bool genericEmail(
string recepient,
string subject,
string bodyMessage,
Dictionary<string, string> replacementStrings = null,
string cc = "",
string bcc = "",
string headerMessage = "",
string footerMessage = "",
FileInfo[] attachments = null,
string[] filenames = null,
EmailMessage originalEmail = null,
ExchangeService exchangeClient = null)
{
EmailMessage email = new EmailMessage(exchangeClient);
email.Sender.Address= config.exchangeUsername + "#domain.com";
email.Sender.Name = "ABC";
if (recepient.Length == 0) {
email.ToRecipients.Add(ABCTeamEmail);
}
else
{
email.ToRecipients.Add(recepient.TrimEnd(';'));
}
if (cc.Length != 0)
email.CcRecipients.Add(cc.TrimEnd(';'));
if (config.environment != "PR")
{
email.Sender.Address = config.exchangeUsername + "#domain.com";
email.CcRecipients.Add(null);
}
if (attachments != null)
{
int i = 0;
foreach (FileInfo fi in attachments)
{
FileStream theStream = new FileStream(fi.FullName, FileMode.OpenOrCreate);
if (filenames == null)
email.Attachments.AddFileAttachment(fi.Name, theStream);
else
email.Attachments.AddFileAttachment(filenames[i], theStream);
i++;
}
}
if (originalEmail != null)
{
string originalEmailFilename = config.extractFolder + "\\Emails" + originalEmail.Subject.Trim().Replace('\\', '_').Replace('/', '_').Replace(":", "_").Replace("\"", "_").Replace("*", "_").Replace("?", "_").Replace("<", "_").Replace(">", "_").Replace("|", "_") + "_" + originalEmail.DateTimeReceived.ToString("yyyyMMdd_HHmmss") + ".msg";
originalEmail.Save(originalEmailFilename);
email.Attachments.AddFileAttachment(originalEmailFilename);
}
if (config.environment == "PR")
email.Subject = subject.Trim();
else
email.Subject = "[" + config.environment + "] " + subject.Trim();
if (replacementStrings != null)
{
foreach (KeyValuePair<string, string> kv in replacementStrings)
{
bodyMessage = bodyMessage.Replace(kv.Key, kv.Value);
}
}
bodyMessage = bodyMessage.Replace("{headerMessage}", headerMessage);
bodyMessage = bodyMessage.Replace("{footerMessage}", footerMessage);
email.Body = new MessageBody(bodyMessage);
email.Send();
return true;
}
}
ews_oauth_adapter.genericEmail(respondTo, "RE: " + msgDetail.Subject.ToString() + " Incorrect Physical Name", physcalNameErrorMessage + BottomOfEmail + "<br><br><hr><br>" + msgDetail.Body, null, cc, "", "", "", null, null, null, exchclient);
**Getting the exception when calling the function genericEmail **
Not able to identify precisely what is wrong with my implementation. Went through some similar issues like Error while sending Email :you must load or assign this property before you can read its value -EWS. But couldn't find the same issue in my implementation.
#UPDATE
try
{
inbox_mails = tokenProvider.ReadEmailFromFolder(-5, 50, Inbox_ID.Id);
foreach (Item mailItem in inbox_mails)
{
EmailMessage mes = (EmailMessage)mailItem;
Console.WriteLine("\nRunning message: " + mailItem.Subject.ToString() + " From: " + mes.From.ToString());
logger.log("\nRunning message: " + mailItem.Subject.ToString() + " From: " + mes.From.ToString());
Console.WriteLine(mes.Body); // Showing the exception when trying to print the Mail Body.
//TestPortRequestOauthBased dataloader = new TestPortRequestOauthBased(config, logger, dbCommands, exchClient, mailItem);
}
Thread.Sleep(sleepInterval);
}
catch(Exception e)
{
Console.WriteLine("The operation timed out!! ");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
//ews_oauth_adapter.genericEmail(cc, "FATAL ERROR: Integration TestPort System", "System has crashed and needs to be restarted <br><br>" + e.Message + "<br>" + e.StackTrace, null, "", null, "", "", null, null, null);
throw e;
}
public FindItemsResults<Item> ReadEmailFromFolder(int mailSince, int mailLimt, FolderId folder_id)
{
TimeSpan ts = new TimeSpan(mailSince, 0, 0, 0);
DateTime date = DateTime.Now.Add(ts);
SearchFilter.IsGreaterThanOrEqualTo filter = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, date);
var findResults = exchangeService.FindItems(folder_id, filter, new ItemView(mailLimt));
return findResults;
}
That error is telling you your trying to load a property you never requested from EWS. When you call that function you have
msgDetail.Body
Where is the code you get msgDetail from it most likely you haven't ever requested to return the body of the message in this code and it isn't returned by default in FindItems so with msgDeail there should have been a load at some point
I'm building a c# console application which read messages from MSMQ(Microsoft Message Queuing), I expected it to run forever but after a day running it stop reading message from MSMQ until I right click on its Console, my problem seems to be alittle bit similar to this: "Console Application "pausing" c#". Bellow is the function that I'm using:
private static void downloadHandler(object args)
{
while (true)
{
while (CURRENT_ACTIVE_THREAD < MAX_THREAD)
{
DownloadController.WriteLog("Current active Thread = " + CURRENT_ACTIVE_THREAD);
Console.WriteLine("Current active Thread = " + CURRENT_ACTIVE_THREAD);
Thread.Sleep(1000);
MessageQueue messageQueue;
if (MessageQueue.Exists(messageQueuePath))
{
messageQueue = new MessageQueue(messageQueuePath);
Message requestMessage = messageQueue.Receive();
try
{
requestMessage.Formatter = new BinaryMessageFormatter();
string msg = requestMessage.Body.ToString();
if (!string.IsNullOrEmpty(msg))
{
DownloadController.WriteLog("received message with message = " + msg);
CURRENT_ACTIVE_THREAD += 1;
RequestDownload request = new RequestDownload();
request = JsonConvert.DeserializeObject<RequestDownload>(msg);
DownloadController.WriteLog("received message with contentId = " + request.contentId + "from message queue | title= " + request.contentTitle + " | url = " + request.baseURL);
DownloadController downloader = new DownloadController();
Thread t = new Thread(new ParameterizedThreadStart(downloader.findURLandDownload));
object[] objs = new object[2];
objs[0] = request;
objs[1] = "1";
t.Start(objs);
Console.WriteLine("received message with contentId = " + request.contentId);
}
}
catch (Exception ex)
{
CURRENT_ACTIVE_THREAD -= 1;
Console.WriteLine("Exception: " + ex.Message);
DownloadController.WriteLog("There is exception while trying to read message from message queue, Exception = " + ex.Message);
}
}
}
}
}
So,could anyone please tell me what the problem is? Why this happening?
It might be you're while loop. I had while loops freeze or break my applications before. Might i suggest using timers instead ? I have some links you could use for reference:
c# wait for a while without blocking
https://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx
I do hope this fixes the problem you're having !
greatings,
Ramon.
I'm working with RabbitMQ on someone else's project and having trouble with dequeuing and missing data.
The data is all there as a string when I publish, and it's also on there correctly on the RabbitMQ queue. When I pull the data off, buts of the data is there like the User ID, but the rest of it is gone. I've looked throughout the code and I'm fairly positive that its something going on with RabbitMQ, and its happening when I dequeue. Any help would be greatly appreciated. Thanks.
Here is the code right before the publish.
private bool sendJobToMQ(EncodeJobModel job, string p_correlation_id, string p_request_routing_key)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
StringBuilder sb_job = new StringBuilder();
ser.Serialize(job, sb_job);
string rpc_reply_queue;
ConnectionFactory factory = new ConnectionFactory();
factory.HostName = HOST_NAME;
factory.VirtualHost = VHOST_NAME;
factory.UserName = USERNAME;
factory.Password = PASSWORD;
IConnection rabconn = factory.CreateConnection();
IModel sender_channel = rabconn.CreateModel();
try
{
sender_channel.ExchangeDeclare(EXCHANGE_NAME, ExchangeType.Direct, true, false, null);
}
catch (Exception err)
{
logger.Error("Error Declaring Exchange " + EXCHANGE_NAME + ": " + err.ToString());
return false;
}
try
{
sender_channel.QueueDeclare(REQUEST_QUEUE, true, false, false, null);
}
catch (Exception err)
{
logger.Error("Error QueueDeclare (" + REQUEST_QUEUE + " true, false, false, null): " + err.ToString());
return false;
}
try
{
sender_channel.QueueBind(REQUEST_QUEUE, EXCHANGE_NAME, REQUEST_ROUTING_KEY, null);
}
catch (Exception err)
{
logger.Error("Error QueueBind (" + REQUEST_QUEUE + " -> " + EXCHANGE_NAME + " " + REQUEST_ROUTING_KEY + ", null): " + err.ToString());
return false;
}
//rpc_reply_queue = sender_channel.QueueDeclare("rq_" + job.encodejob_id.ToString(), false, false, true, null);
//////bind the rpc reply queue to the exchange via a routing key (I appended _routingkey to signify this)
//sender_channel.QueueBind(rpc_reply_queue, EXCHANGE_NAME, rpc_reply_queue + "_routingkey");
//// Not sure what the props object is for yet but you can try to pass null in the mean time - Steve "Apeshit" Han
BasicProperties props = new BasicProperties();
props.CorrelationId = p_correlation_id;
//props.ReplyTo = rpc_reply_queue;
try
{
sender_channel.BasicPublish(EXCHANGE_NAME, REQUEST_ROUTING_KEY, props, Encoding.UTF8.GetBytes(sb_job.ToString()));
}
And the code for the dequeue.
QueueingBasicConsumer consumer = new QueueingBasicConsumer(p_channel);
string consumerTag = p_channel.BasicConsume(p_queue, false, consumer);
if (_is_console && Environment.UserInteractive)
Console.WriteLine("Listening...");
while (m_Listen)
{
try
{
//get the properties of the message, including the ReplyTo queue, to which we can append '_routingkey' (designated by me), to reply with messages
BasicDeliverEventArgs e;
Object message;
if (!consumer.Queue.Dequeue(4000, out message)) {
// we do not wait to indefinitely block on waiting for the queue
// if nothing in queue continue loop iteration and wait again
continue;
}
// cast as necessary back to BasicDeliverEventArgs
e = (BasicDeliverEventArgs)message;
IBasicProperties props = e.BasicProperties;
//get the Correlation ID sent by the client to track the job
string client_correlation_id = props.CorrelationId;
// I left out the reply_to field in the wizard, it can be set back in ApiEncodeServiceDefault - Steve "Smurfing Smurf" Han
//string reply_to = props.ReplyTo;
//get the body of the request
byte[] body = e.Body;
string body_result = Encoding.UTF8.GetString(body);
bool redelivered = e.Redelivered;
The e.Body string is missing data.
why continue if you don't have any message
it is better to block until you receive a message otherwise the process is not interesting (work with no data?)
try like this
QueueingBasicConsumer consumer = new QueueingBasicConsumer(channel);
channel.BasicConsume(queueName, null, consumer);
while (m_Listen) {
try {
RabbitMQ.Client.Events.BasicDeliverEventArgs e =
(RabbitMQ.Client.Events.BasicDeliverEventArgs)
consumer.Queue.Dequeue();
IBasicProperties props = e.BasicProperties;
byte[] body = e.Body;
// ... process the message
channel.BasicAck(e.DeliveryTag, false);
} catch (OperationInterruptedException ex) {
// The consumer was removed, either through
// channel or connection closure, or through the
// action of IModel.BasicCancel().
break;
}
}
I have implemented asp.net caching. But I am getting weird results
Unlike most caching where you are trying to avoid the amount of hits to the DB. I am trying to avoid any hits to the DB by the user. This is b/c the amount of time the fist page takes to load. It is basically a dashboard with a lot of charts and long running queries
I tried several techniques
1) Have the cache time very long and have a schedule process expire and get new cache.
2) and on RemoveCallback
In the second option I have all the cache go through a static class I created. The purpose is as it expires to refresh the data. Here is what I am calling.
Cache.Insert(dbCacheString, dtNetwork, null, DateTime.Now.AddHours(2),
System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High,
new CacheItemRemovedCallback(CacheManager.CacheRemovedCallback));
public static class CacheManager
{
private static Hashtable times = new Hashtable();
private static bool isRefreshingCache = false;
public static void CacheRemovedCallback(String key, object value,
CacheItemRemovedReason removedReason)
{
RefreshCache(key);
}
public static void StartCache()
{
string lcUrl = "http://localhost/ratingspage/";
// *** Establish the request
try
{
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("xxx", "xxx",
"xxx");
byte[] myDataBuffer = client.DownloadData(lcUrl);
}
catch (Exception ex)
{
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
}
public static void RefreshCache(string key)
{
string controlname = "";
if ( key.ToLower().StartsWith("control:") )
{
string[] tmp = key.Split(':');
if (tmp.Length > 1)
controlname = tmp[1];
else
return;
}
else
return;
string lcUrl = "http://localhost/ratingspage/Admin/" + "
"LoadControl.aspx?CachingSpider=true&Control=" + controlname;
string lcHtml = isRefreshingCache.ToString();
// *** Establish the request
if (!isRefreshingCache)
{
isRefreshingCache = true;
lcHtml = isRefreshingCache.ToString();
try
{
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("xxx",
"xxx", "xxx");
byte[] myDataBuffer = client.DownloadData(lcUrl);
lcHtml = Encoding.ASCII.GetString(myDataBuffer);
}
catch (Exception ex)
{
lcHtml = ex.Message;
isRefreshingCache = false;
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
isRefreshingCache = false;
}
MailMessage mail = new MailMessage(
new MailAddress("jgiblin#univision.net"),
new MailAddress("jgiblin#univision.net"));
mail.Subject = "Cache Expire: " + key;
mail.Body = string.Format("The Key {0} has expired at {1}",
key, DateTime.Now.ToShortDateString() + " " +
DateTime.Now.ToShortTimeString()) + "\nRefreshing Cache: " +
lcHtml;
SmtpClient smtp = new SmtpClient("mercury.utg.uvn.net");
mail.IsBodyHtml = false;
try
{
smtp.Send(mail);
}
catch (Exception ex)
{
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
}
}
for some reason, when I go to the page. Someone times the data is cached and sometimes it is not. Is there something wrong here
I tried app fabric but since the server does not have iis 7 I am not able to use that
Looks to me like you may have a race condition in your RefreshCache call. Check out this great answer for suggestions on how to handle synchronization:
C# version of java's synchronized keyword?
If I were you, I'd simplify my code. You only really need:
when the application starts up, load the cache
when the cache expires, reload it
if a user tries to access the cached object and misses, sleep their thread for a second and check again
The amount of data you can get into the cache may be the issue.
If the cache is full then the data will obviously not be cached.
You can check your memory allocation using the process monitor, have a look in "Cache Total Entries."