Hi Michael,

I've had similar problems here.

It sounds like you might be missing a "QUIT". This closes the mail server.

   else if (RqType = smtpMail) and (ErrorCode = 0) then
   begin
     sgProgress.Value := 90;

     // -- Write every entry
     for xc :=1 to SmtpEmail.EmailFiles.Count do
       Report('SENT','Successfully sent ' +  
SmtpEmail.EmailFiles.Strings[xc-1]);

     SmtpEmail.Quit;

   end
   else if (RqType = smtpQuit) and (ErrorCode = 0) then



Quoting Michael Kochendoerfer <[EMAIL PROTECTED]>:

> Arno and all,
>
> I realized and appreciated your hint to perform it all event-driven and
> I tried to accomplish it the way you suggested. However, I have some
> problems building the correct logic, it seems. In short words, the mail
> sending part of my application is as follows:
>
> 1. Opening a SQL server query
> 2. Fill the standard properties (like Host, Port etc.) which are common
> between calls
> 3. Invoking my OnGetNextMailParam notify procedure *directly*, as if it
> had been called from the OnRequestDone handler
> 3a. OnGetNextMailParam checks if the query has still records, read some
> fields, sets HdrTo if the record contains an mail address, calls
> Connect() and Next() for the query
> 3b. OnGetNextMailParam calls a message handler procedure if there's no
> target mail address, which invokes 3 again.
> 4. OnRequestDone is built like the sample code in MailSnd1.pas, except
> for the smtpQuit part. In my handler, OnGetNextMailParam is called
> again, and if it reports a valid target address, it calls Connect()
> again (if not, it should have been handled by 3b)
>
> This all should work from the beginning of the query to the end, where
> each record containing a target address should invoke the sending
> process and each other record should not (records without an mail
> address are handled otherwise). But it doesn't - it calls Connect() for
> two records and then it leaves.
>
> I don't like you all to analyze my procedures but I'm looking for some
> basic framework which would do it. I first thought of building the whole
> procedd into the smtpConnect part of OnRequestDone, but this isn't
> possible due to the lack of mail addresses in some of the records. I'm
> really stuck here and I now realize my concept won't work as needed.
>
> The whole thing is not more or less than walking through a record set
> and sending a mail to each receiver within that record set having a mail
> address. Other records having no mail address are handled otherwise,
> must be processed within the same loop but don't invoke any mail sending
> process. And - of course - it should be async ;)
>
> TIA,
> Michael
>
>
> Arno Garrels schrieb:
>
>>> while not FlagDone do begin
>>>  //Application.ProcessMessages;  // Don't know whether or not to use
>>> the message pump here   Sleep(50);
>>> end;
>>>
>>>
>>
>> This is bad design. Do not wait in a loop. While sleeping the calling
>> thread is blocked. Instead let your derived component do the work in
>> the background. In order to get notified when the job has finished add
>> a custom event that fires when the work is done, or may be add another
>> custom event that notifies the application when a single message has
>> been sent/failed. In other words, control the application completely
>> thru events while executing the mailing. So in the ButtonClick handler
>> there the call to start the mailing should be the very last line.
>>
>> ---
>> Arno Garrels [TeamICS]
>> http://www.overbyte.be/eng/overbyte/teamics.html
>>
>>
>> Kochendoerfer, Michael wrote:
>>
>>
>>> You all are giving excellent information in this mailing list, thanks
>>> a lot!
>>>
>>> I guess my problem is - as you describe - that the component is still
>>> active, even if smtpQuit has been reached within OnRequestDone. I
>>> don't currently check if it's still connected, but I will change it.
>>> Errors will be checked and force to abort the entire mail and write
>>> some log entries.
>>>
>>> As Arno said earlier, I'd like to have async components because of
>>> their benefits. But in fact, for me it is a sync call, at least for
>>> each single mail. IOW, I've to wait until each particular mail has
>>> been finished before I'm advancing to the next one. So I'm starting
>>> with Connect(), let the OnRequestDone do the background stuff and set
>>> a flag if either aborted or quit. Now I know I've to wait also for
>>> not Connected. But what's the correct method to wait for completion?
>>> Currently, I have a loop after calling Connect() looking like this:
>>>
>>> while not FlagDone do begin
>>>  //Application.ProcessMessages;  // Don't know whether or not to use
>>> the message pump here   Sleep(50);
>>> end;
>>>
>>> Any thoughts?
>>>
>>> TIA,
>>> Michael
>>>
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: [EMAIL PROTECTED]
>>>> [mailto:[EMAIL PROTECTED]
>>>> Behalf Of DZ-Jay
>>>> Sent: Tuesday, January 16, 2007 10:57 AM
>>>> To: ICS support mailing
>>>> Subject: Re: [twsocket] Still problems while sending SMTP
>>>>
>>>>
>>>>
>>>> On Jan 16, 2007, at 02:49, Arno Garrels wrote:
>>>>
>>>>
>>>>
>>>>> When the response to the Quit command is received the connection
>>>>> (may) still be alive. So watch both, whether Quit response has been
>>>>> received as well as the SessionClose event. Call connect only
>>>>> after the session has been closed.
>>>>> Don't start a loop directly from an event handler but post a custom
>>>>> message to some Window, in it's message handler start the next loop.
>>>>>
>>>>>
>>>> You could, in fact, re-use the connection if the next message
>>>> is to be
>>>> sent through the same server.  All you have to do is, after the DATA
>>>> command is completed and the server acknowledges receipt, check
>>>> SmtpCli.Connected, if you are still connected then reset your
>>>> state-machine to start the cycle fromthe MAIL FROM command.  Some
>>>> servers required a "reset" (RSET) command be sent to reset state, and
>>>> it doesn't hurt to send it anyway.  The important thing is to
>>>> check the
>>>> connection, because something may have happened -- and indeed, some
>>>> servers have anti-spamming filters that will kick you out after
>>>> receiving DATA that they determine is spam, and some won't
>>>> allow you to
>>>> re-send after one message.  So the algorithm would be something like:
>>>>
>>>> 1. Connect
>>>> 2. HELO
>>>> 3. MAIL FROM
>>>> 4. RCPT TO
>>>> 5. DATA
>>>> 6. If connected:
>>>> 6.a (yes) RSET then back to 3
>>>> 7. QUIT
>>>> 8. back to 1
>>>>
>>>> Of course, you should check for errors after each step (in
>>>> OnRequestDone, before changing states).  Keep in mind that
>>>> some errors
>>>> are recoverable (transient: 400+), some errors are not
>>>> (non-transient:
>>>> 500+), and some are somewhere in between (like RCPT warnings, etc).
>>>> Recoverable errors allow you to try again, or require a RSET
>>>> and start
>>>> from step 3, while non-transient errors require closing the
>>>> connection
>>>> and starting from scratch.  If you are sending general messages to
>>>> strange servers "in the wild" it gets pretty complicated, specially
>>>> when you factor in all the non-RFC-compliant servers; but if your
>>>> application is of limited purpose, sending using the same server all
>>>> the time, the errors and issues that may occur are predictable and
>>>> substantially less.
>>>>
>>>> Building this logic in a simple state-machine using
>>>> OnRequestDone makes
>>>> it fairly easy to make your application powerful and efficient -- the
>>>> reason we always push for the use of async methods.
>>>>
>>>> dZ.
>>>>
>>>> --
>>>> DZ-Jay [TeamICS]
>>>> http://www.overbyte.be/eng/overbyte/teamics.html
>>>>
>>>> --
>>>> To unsubscribe or change your settings for TWSocket mailing list
>>>> please goto http://www.elists.org/mailman/listinfo/twsocket
>>>> Visit our website at http://www.overbyte.be
>>>>
>>>>
>
>
> --
> To unsubscribe or change your settings for TWSocket mailing list
> please goto http://www.elists.org/mailman/listinfo/twsocket
> Visit our website at http://www.overbyte.be
>


-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://www.elists.org/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to