I have created an IMAP-Server. Now I am searching a way to force the client (in my case an iPhone) to reload a message, because it has changed on the server-side. Does somebody know a way to do this?
The body of a message is not allowed to change in IMAP; the only data item that may be changed for an existing message is the list of flags.
If you want to mimic a change in message body, you effectively have to tell your client that the original message was removed, and a new one created. You achieve the former by sending an EXPUNGE response with the message’s original sequence number, and the latter by sending an EXISTS and/or RECENT response, after which the client would typically issue a FETCH command for the new message.
The IMAP server can't force the IMAP client to do anything.
The closest thing to what you're looking for is IMAP IDLE. With IMAP IDLE, the server can push certain notifications to the client (if the client asked to receive them). The client can then do whatever it wants when it gets those notifications.
Related
I can just reply to the sender, but the reply packet may not get to the other side too, which leaves me in an infinite loop...
Thanks in advance.
This is off topic, and there's tons of information on this on the internet.
What I would do is reply to the sender with an "OK", passing a packetId with it so that the sender knows to which packet he receives an OK. If the sender does not get an OK within 30 seconds (or whatever) he sends the package again (with the same packageID). The retriever handles the package again, unless he already got it. In both cases he will send an OK package to the sender. So the sender does not know whether or not his message went wrong, or whether the retrievers message went wrong. It really doesn't matter too, if you use packageIds.
BTW, UDP is a protocol that typically does not promise for a package to get to its destination. So if you do want to guarantee this, you should probably just use a different protocol (i.e. TCP).
What is the best way to be notified instant when mails or changes happens to the INBOX of my mailbox using MailKit??
I have been playing around with following events:
ImapClient.Inbox.CountChanged; This seems to work best when using Exchange servers, since they don't react at all on the MessageArrived event. Pff..
ImapClient.Inbox.MessagesArrived; This seems to work quiet well with open source mail servers, like SquirrelMail, but doesn't work at all with Exchange.
I want to be notified when new mails arrive to the mailbox, if any mails are moved/deleted, and if there any mails moved to this imap folder. Which approach should I take to get an event asap when something happens to my INBOX?? I want the best of both worlds.
And what is the ImapClient.Inbox.Subscribe(); used for??
The Subscribe and Unsubscribe methods just flag a folder (aka mailbox) as subscribed or unsubscribed - generally this is only used by mail clients to decide whether or not the user wants to see the folder in the default folder list.
The CountChanged event is emitted anytime MailKit gets an untagged "* # EXISTS" line from the IMAP server, typically as part of a response to a command that was just sent.
The MessagesArrived event is emitted immediately following the CountChanged event IF AND ONLY IF the new message count is larger than the old message count. Unfortunately, this is a badly designed/named event because it can be very misleading. Since the logic that determines whether or not to emit the event only has limited context (the old message count and the new message count), it can't accurately decide whether or not to emit this event.
Take the following situation for example:
When you open a folder, let's say that the message count is 10.
Now you expunge a handful of messages (5?) out of the folder... BUT, while the messages are being expunged, you get 2 new messages.
When the expunge command completes, the IMAP server replies back with "* 7 EXISTS"
Since 7 (the new message count) is less than 10 (the old message count), the MessagesArrived event will not be emitted.
I want to be notified when new mails arrive to the mailbox, if any mails are moved/deleted, and if there any mails moved to this imap folder.
If you want to know when new messages arrive, you need to listen to the CountChanged event and do your own book keeping to figure out if new messages arrived or if messages were moved/deleted out of the folder.
There's no way to distinguish between messages being moved into the folder vs new messages being delivered to the folder (unless you are doing the moving).
Which approach should I take to get an event asap when something happens to my INBOX??
If your server supports the IDLE extension, you'll probably want to look into using the ImapClient.Idle() (or IdleAsync()) method since the CountChanged event will only be emitted when it receives a "* # EXISTS" response from the server, and an IMAP server will only send that response as part of a response to a command from the client or if the client is in the IDLE mode.
If your server does not support the IDLE extension, you will need to "ping" the IMAP server using the ImapClient.NoOp() method (which is a dummy command that doesn't do anything) periodically in order to check if any new messages have arrived since the last command you sent.
There's an ImapIdle sample in MailKit's GitHub repository to see how to use it.
The SmtpClient send method returns void. Is there any way to get the server response? Do I just assume it was successful unless it throws an exception?
The class I'm referring to... http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.aspx
To answer your second point, yes, all you can do is assume it's successful - meaning it got the message to the server and the server accepted it, unless you get an exception.
You probably already know the rest of this, but just in case...
From there, the email could get lost and not delivered any number of ways. Your server may accept it and decide not to send it, or accept it and lose power before crashing. It may get blocked by a spam filter along the way, etc.
You can think of an email as being similar to a regular piece of mail in that it passes through several hands between the sender and the recipient. From your code, you can only confirm that it got to the SMTP server you're using to send, which is similar to handing it to a teller at the post office. You don't know (or need to know) how the message is routed from there. it could be by air, ground, or carrier pigeon. You're out of the equation - you don't need to know how it gets sent, just that you trust that they know how to send it. (The same can be said for an email.)
If you need to confirm that the recipient opened it, there are ways of embedding an image in an HTML message on your server and tracking in your logs when that image is accessed, etc. (Google email tracking and email open tracking)
On the other hand...
If the server rejects it, then you do get a server response in a manner of speaking - there should be an error code and a description in the error, which you can use to troubleshoot why it didn't make it, or use error handling to try another route, etc.
You can utilize SendCompleted Event to check that your smtpclient works fine like this:
http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.sendcompleted.aspx
But you cannot get confirmation that your message reached recipient because it may stuck in any server/filter in message chain.
You assume that it was successful unless it throws... although success in this case only means that it was accepted by the mail server, anything else is then up to the server...
IF you want a little bit of control you can use SendAsync and hook the SendCompleted event...
I am trying to send a message with attachment using CDO object. When the SMTP Server is available and all the information is correct, the message is correctly sent with the attachment.
However, if the SMTP Server is incorrect the message is not sent (as expected), but it seems to be "stuck" somewhere. I am using:
Fields["http://schemas.microsoft.com/cdo/configuration/sendusing"] = 2
I've searched over the Internet, and found that this option would give a 60 second timeout. But the file I attached to the message is never available.
The test that I've done is to send a message with an attached file and using an invalid SMTP Server. Then, I wait for a few minutes and try to delete the file I had attached. However, when I try do it, I have a permission problem. When I kill the sending email program, I am able to delete the file.
I want to know how to configure the timeout to make sure it gives up sending the message, how I "detach" the file when the message is not sent and how to make the program wait for the message to be sent (I want to send the message and then erase the attached file from the computer. So I need to know when the message was really sent or when it was timedout).
CDO is hopelessly obsolete, you really need to consider switching to System.Net.Mail. The specific problem sounds like a file locking issue. Quacks like a bug in CDO, it would open the attachment to compose the email message but forgets to close the file when the SMTP server balks.
This bug is probably exacerbated by the way .NET deals with COM servers, like CDO. The COM object doesn't get released until the garbage collector runs. Which can take a while, especially when your program doesn't do anything significant after trying to send the email. A workaround for that is calling Marshal.ReleaseComObject() on the CDO object. Tends to not work when you have other CDO interface references in your program, those references tend to be hidden. GC.Collect() + GC.WaitForPendingFinalizers() is the big hammer, after you nulled any object reference.
But, really, use System.Net.Mail.
I was wondering if anyone could help me out (not with code, although that would be appreciated), with the logic behind checking and retrieving messages from a POP3 mail server.
I.e.
Establish connection
Validate credentials
Enumerate message list
Check each message to see if it's "new"
Download "new" message(s).
Would this be the correct way about doing this?
Thank you
The best way of looking at something like this is to have a look what something else does. Run Wireshark or some other packet capture software, and use an e-mail client to check. Anyway, the basics of a POP3 session are as follows:
USER username
PASS password
LIST <-- Shows the size of each waiting message
UIDL <-- Shows a unique ID for each waiting message
RETR 1 <-- Retrieves message with index 1
DELE 1 <-- Deletes the message you just retrieved
QUIT
The first char of all of the responses except RETR will be a + (success) or a - (failure).
If you are deleting messages off the server after retrieving them, you don't need to bother with UIDL. If you are leaving them, you can use UIDL to get a unique ID for each message which you store locally to show you have retrieved that message before.
For more details, see the RFC. Wikipedia also lists a more in depth example, showing the server response.
These should be useful:
POP3 Email Client (.NET 2.0)
POP3 Client as a C# Class
Retrieve Mail From a POP3 Server Using C#
POP3 Sequence Diagram
POP3 Reference