Bulks Emails not reaching destination, lost in network - c#

I am sending approximately 5000 emails to IIS smtp server Windows 2012 R2 (Server1) using aspose email client (using c#) in a loop. The emails fired queue up in smtp server queue. From that queue, they are all sent to the same destination (an oracle email filing server - Server2).
The problem is - approx 700-800 (randomly every time) emails are getting lost in transit.
Questions -
Is there any way that i can queue all the emails received on Server1 to ensure that it is receiving complete 5000 emails? Any setting, so it can receive emails but do not forward them?
Is smtp email delivery not guaranteed to the recipient? Since there is no throttling mechanism, i think i am choking the network by sending large number of emails, and then emails in lost in network. If it is so, is there a mechanism by which smtp server can be configured to process queue slowly. Send out a few and then wait and so on.

Aspose.Email also let you send the email in the form of bulks as well. Moreover, it is also dependent on server side that how much bulk email it may handle at any given time so as to avoid any bombardment of emails as well. There may be settings on server side. However, from Aspose.Email perspective, you may please consider using following sample code rather than sending via loops. You can divide big chunks of emails into small bulks and then send via Bulk email sending option provided by Aspose.Email.
SmtpClient client = new SmtpClient("mail.server.com", 25, "Username", "Password");
//Create instances of MailMessage class and Specify To, From, Subject and Message
MailMessage message1 = new MailMessage("msg1#from.com", "msg1#to.com", "Subject1", "message1, how are you?");
MailMessage message2 = new MailMessage("msg1#from.com", "msg2#to.com", "Subject2", "message2, how are you?");
MailMessage message3 = new MailMessage("msg1#from.com", "msg3#to.com", "Subject3", "message3, how are you?");
//Create an instance of MailMessageCollection class
MailMessageCollection manyMsg = new MailMessageCollection();
manyMsg.Add(message1);
manyMsg.Add(message2);
manyMsg.Add(message3);
//Use client.BulkSend function to complete the bulk send task
try
{
// Send Message using BulkSend method
client.Send(manyMsg);
Console.WriteLine("Message sent");
}
catch (Exception ex)
{
Trace.WriteLine(ex.ToString());
}

Related

How do I receive messages from an Artemis multicast queue in C#?

I'm up to send and receive messages over ActiveMQ Artemis with C# applications. In Anycast-mode, everything is working.
When i tried to send and receive in multicast-mode, i can send, but i don't receive any of the messages from the queue.
I tried the trick from java, set the "multicast" flag before the tcp uri, but an error message shows up that there isn't an implementation for "multicast"
private void Receiver()
{
IConnectionFactory factory = new NMSConnectionFactory("multicast:tcp://172.29.213.150:61616");
IConnection connection = factory.CreateConnection("artemis", "simetraehcapa");
connection.Start();
ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
IDestination destination = SessionUtil.GetDestination(session, "hund");
IMessageConsumer receiver = session.CreateConsumer(destination);
receiver.Listener += new MessageListener(Message_Listener);
}
Normally I would receive the messages, because I only switched from anycast to multicast, but actually I receive nothing.
If using the AcitveMQ OpenWire NMS client you don't apply that odd multicast thing you've done to the URI, that will give you an error. The client should just work if you use the Session API and not that confusing SessionUtil API that has resulted in many people running into issues.
I'd use Session.CreateTopic to get an ITopic instance and then create a consumer using that which should map over into Artemis Multicast addresses without you needing to do anything. You do of course need to be subscribed before any messages are sent as Topics don't retain messages if no consumers are around when the are sent.

Why does SmtpClient fail with several different Exceptions when using SSL?

I'm trying to send a mail message using System.Net.Mail.SmtpClient with SSL enabled. While changing no external factors (i.e. hit F5, then hit F5 Again - or even in a loop) it works some times, but most of the times it fails.
Example code:
public void SendMail()
{
using (var client = new SmtpClient())
{
MailMessage mailMessage = new MailMessage();
client.EnableSsl = true;
client.Host = "smtp.example.com";
client.Timeout = 10000;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
mailMessage.From = new MailAddress("from#example.com");
mailMessage.To.Add(new MailAddress("to#example.com"));
mailMessage.Subject = "Test";
mailMessage.Body = "Message " + DateTime.Now.ToString();
try
{
client.Send(mailMessage);
}
catch (Exception ex)
{
// This being a Pokemon block is besides the point
}
}
}
In my catch block I just get a timeout, but if I set up a trace for System.Net and System.Net.Sockets I can see a number of different exceptions:
Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall
Unable to read data from the transport connection: An established connection was aborted by the software in your host machine
Cannot access a disposed object
Reading is not supported on this stream
Writing is not supported on this stream
All of which happen post EHLO, STARTTLS and authentication. The client and the server are chatting along in their cryptographic ways when the exceptions are thrown.
System.Net.Mail.SmtpClient.Send() is the the only frame all call stacks have in common.
Of course I've tried changing the code in a number of ways, such as setting client.UseDefaultCredentials, using client.SendAsync() and whatnot. But I suspect it's something entirely different knocking the connection over at different times - a configuration error on one of the machines involved perhaps?
So I've checked the Event Logs for signs of something messing with the connection, but I haven't found anything.
Any suggestions as to what I should be looking for here?
Sometimes a timeout is just a timeout ...
Digging further into this issue I used Wireshark to see what was going on at the network level.
When the failures happened, the client machine invariably sent a TCP [RST, ACK] packet around 10 seconds after EHLO. A timespan conspicuously close to my timeout value. When I doubled the timeout value the mails came through without failure every single time.
Of course if we were to spend more than 10 seconds sending each mail, we'd soon be queuing up mails for hours in our production system, so I needed to find out why it took so long.
One detail caught my attention:
The client was spending upwards of four seconds between two packets. And it was generally spending hundreds of milliseconds between packets whereas the server would respond within tens.
The next step was to build the code without debug symbols and measure again without a debugger attached. The time spent per e-mail sent immediately went sub-second. Now it's no news to me that code runs slower with a debugger attached, but seeing it run that much slower was a surprise.
So the lessons for me to learn were: Try not to overanalyze, and when timing is involved kill the debugger once in a while.
This should be a comment (I don't have reputation to make comments), but it could be a firewall issue, given you're getting an "Unable to read data from the transport connection: An established connection was aborted by the software in your host machine" error (basically, firewall or anti-virus cancelled your attempt to send a mail).
The error "Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall" happens when a stream is closed - see this question - and the other errors you've listed seem like they're related to trying to access a stream when it's closed, too.
All these error point to a common cause, a connection cancelled somewhere between you and the server and most likely on your machine/ network, and you get different errors depending at what point the effect propagates through to your application.
Another thing is, if you use
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
then you have to enable ssl afterwards, not before, otherwise it's cleared.
I suppose you have missed to set Credentials property of your host. However the another reason for exceptions may be wrong host name and port.Try something like :
public void SendMail()
{
try
{
var fromAddress = new MailAddress("from#example.com", "Some text");
var toAddress = new MailAddress("to#example.com");
const string fromPassword = "from account password";
var smtp = new SmtpClient
{
Host = "smtp.example.com",
Port = "your host port", //for gmail is 587
EnableSsl = true,
DeliveryMethod = SmtpDeliveryMethod.Network,
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
};
using (var message = new MailMessage(fromAddress, toAddress)
{
Subject = "Test",
Body = "Message " + DateTime.Now.ToString()
})
{
smtp.Send(message);
}
}
catch (Exception ex)
{
//do something
}
}
It is tested with gmail host which is smtp.gmail.com and it works correctly

Improve performance of RabbitMQ publish (RabbitMQ C# client)

I'm using the following code to publish messages to a RabbitMQ queue:
ConnectionFactory factory = new ConnectionFactory {
HostName = hostName,
Port = port,
UserName = userName,
Password = password,
VirtualHost = "/",
Protocol = Protocols.DefaultProtocol
};
connection = factory.CreateConnection();
channel = connection.CreateModel();
channel.QueueDeclare(queue, true, false, false, null);
foreach (string message in messages) {
byte[] body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", queue, null, body);
}
While publishing the messages to a local RabbitMQ server I get a message rate of up to 10,000 messages per second. The cpu load of the system (2x3.16 GHz) is at almost 100%. Is there a way to increase this message rate? My first idea was to use a bulk publish operation, but there doesn't seem to be anything like that in RabbitMQ. My second idea was using a Parallel.ForEach instead of the foreach, but that didn't change the message rate.
Defining a queue as "Durable" has the added benefit of surviving a rabbit or server restart. The downside is that to accomplish this it writes the data to disk, which is costly.
If your greatest concern is throughput and it's not a problem that you'd drop a few messages in the event of a failure than setting "Durable=false" would increase your throughput.
Note: Even with durable=false if the queue length becomes long enough it will dump them to disk (after all, there is only so much memory on the machine).

SmtpClient.SendAsync() not receiving all messages I sent

I've just written some test code looking at the System.Net.Mail.SmtpClient sending identical messages to myself.
int numClients = 10;
List<SmtpClient> mailClients = new List<SmtpClient>();
for (int i = 0; i < numClients; i++) {
mailClients.Add(new SmtpClient(smtpHost));
}
MailMessage msg = new MailMessage("myAddress#eg.com", "myAddress#eg.com", "test message", "" );
foreach (SmtpClient c in mailClients) {
c.SendAsync(msg, null);
}
This is all fine and executes without any problems except that I only receive 'n - 1' messages.
i.e. If I send 10 messages I only recieve 9 in my inbox. If I send 50 I only receive 49 etc.
Note: If I change the code to use a blocking Send then I will always receive the right number of messages.
e.g.
foreach (SmtpClient c in mailClients) {
c.Send(msg);
}
Any ideas?
Here are a few observations that may help:
Only create one SmtpClient.
Create multiple messages instead.
SmtpClient implements IDisposable. Wrap it in using.
MailMessage also implements IDisposable.
I suspect you may be running into a bug/issue with multiple SmtpClient instances that all wrap the same SMTP server. Using a single instance may resolve the issue.
UPDATE
Per MSDN:
After calling SendAsync, you must wait for the e-mail transmission to complete before attempting to send another e-mail message using Send or SendAsync.
http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx
So given your situation, there is almost no benefit to using SendAsync over Send. Your loop is probably stomping on something since you do not wait for the previous SendAsync to complete.
Here are a few thoughts:
SendAsync will perform almost the same as Send if you are sending a bunch of emails. Just use Send.
If you need parallel sending, use a Producer/Consumer pattern. One (or more) producing threads dump stuff into a queue to send, and multiple consuming threads each use one SmtpClient to send messages. This pattern is amazingly simple to implement with a BlockingCollection. See the example in MSDN http://msdn.microsoft.com/en-us/library/dd267312.aspx
If you use enough threads, your SMTP server will be the bottleneck. Be aware of when you are overloading it.

SmtpException - The operation has timed out

Here is my code:
SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = true;
using (client as IDisposable)
{
foreach (MailAddress addr in Addresses)
{
if (addr != null)
{
try
{
message.To.Clear();
message.To.Add(addr);
client.Send(message);
}
catch (Exception ex)
{
Log(ex);
}
i++;
}
}
}
every 100 seconds, I log a message saying
The operation has timed out.
Is this a client side setting or on the actual mail server?
The problem happens when you are not able to connect to SMTP server and thats why this timeout message occur. So this message occurs on your client when your client is not able to connect to your SMTP Server:
100 second is default value as described below:
http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.timeout.aspx
There could be several issue why this prblem could occur i.e. Wrong SMTP address, SMTP reject, Port setting, SSL configuration etc which you need to fix.
I was also expeiencing this timeout. The problem seemed to be that the email I was trying to send out had a single email address but repeated 30+ times (this was a dev environment where the real recipient email addresses were change to a dev one). Cutting this number (to about 20) resolved the issue. Obviously, this is an issue specific to my own SMTP server, but the recipient list is something to look at if all else fails.

Categories

Resources