Does anyone have any SMTP classes for Dolphin at all?
I have one which I've written myself which was working "fine" under Dolphin 5 but seems to be giving me endless grief under Dolphin 6 (mostly this seems to be odd behaviour in reading from the streams and not getting expected content at the right time). I thought I'd take a look out in the world for one thats already out there but the only one I found seemed to be Dolpin 4 based and didn't like loading in. |
> Does anyone have any SMTP classes for Dolphin at all?
I am only aware of Jose S. Calvo's POP & SMTP Sockets ( http://www.smalltalking.net/Goodies/Dolphin/ ), which is possibly what you are referring to? I have never used the SMTP class, but I have used his POP class in D6 without a problem. What kind of behavior do you want? If you just want to send mail, and have not looked at CDO, it is worth a look. You can build messages using CDOIMessage, but you can effectively bypass this, and load your own RFC822 messages. I have added a class side helper method (see below) that creates an instance of CDOIMessage from a .eml file, but you could also create it from a string (by creating an ADODB_Stream on the string). There is some example code in the CDO package comment, but to add to that, you can also set which SMTP server you want to use with something like: configuration := CDOIConfiguration new. fields := configuration fields. (fields item: 'http://schemas.microsoft.com/cdo/configuration/sendusing') value: 2. (fields item: 'http://schemas.microsoft.com/cdo/configuration/smtpserver') value: 'myserver'. (fields item: 'http://schemas.microsoft.com/cdo/configuration/sendusername') value: 'myusername'. (fields item: 'http://schemas.microsoft.com/cdo/configuration/sendpassword') value: 'mypw'. (fields item: 'http://schemas.microsoft.com/cdo/configuration/smtpauthenticate') value: 1. fields interface Update. "Then use CDOIMessage to build a message or create it from your own message, and send it" (CDOIMessage loadFromFile: 'c:\email.eml') configuration: configuration; Send. This is the helper method: !CDOIMessage class methodsFor! loadFromFile: aPathAndFilename | email stream | (stream := ADODB_Stream new) open; charset: 'US-ASCII'; LoadFromFile: aPathAndFilename. email := self new. email dataSource OpenObject: stream InterfaceName: '_Stream'. ^email! ! Steve |
Steve Alan Waring wrote on 06/04/06 17:35:
> I am only aware of Jose S. Calvo's POP & SMTP Sockets ( > http://www.smalltalking.net/Goodies/Dolphin/ ), which is possibly what > you are referring to? I have never used the SMTP class, but I have used > his POP class in D6 without a problem. That sounds like the one I was refering to - when loading the package it complained of missing OIDCxxxx classes or something (I don't have that machine infront of me). > What kind of behavior do you want? > If you just want to send mail, and have not looked at CDO, it is worth > a look. Just sending mail, including SMTP AUTH and optionally SSL. I'm not sure why I didn't use CDO originally actually - I have a requirement of working -without- having MSOffice/Outlook installed and suspect this may have been the reason (can't recall offhand what installs the CDO objects). > (CDOIMessage loadFromFile: 'c:\email.eml') configuration: > configuration; Send. Cool, I'll give it bash... Mark |
Mark,
> Just sending mail, including SMTP AUTH and optionally SSL. I'm not sure > why I didn't use CDO originally actually - I have a requirement of > working -without- having MSOffice/Outlook installed and suspect this may > have been the reason (can't recall offhand what installs the CDO objects). CDO is actually a wrapper for "CDO for Win2K" which is a very different thing from the /other/ CDO which talks MAPI to MS Exchange. "CDO for Win2K" is a pure TCP/IP implementation of the real-world's email standards. As far as I can tell, it's just the engine from Outlook Express[*] (not Outlook), and uses its defaults (for the servers, etc) unless you specify otherwise. ([*] and correspondingly limited.) BTW, what kinds of problems were you seeing with the D6 sockets, and were you using the new sockets package or the old one ? -- chris |
The CDO stuff seems to be working nicely, its good to know its not the
old CDO/MAPI evilness. The problems I was seeing with the D6 sockets (and it was the sockets classes that came with a fresh D6 image) were quite possibly more to do with my code than anything, but I was seeing some timing issues where code would work when single stepping but fail when running. However, the main problem I was seeing had to do with content I was reading in from the readStream on the socket. After sending my initial EHLO commands to the SMTP server - a telnet session showed I was getting 5 lines of text back straight away, but for some reason dolphin was only seeing 1 line, after sending additional content to the writeSocket, subsequent reading of readSocket showed the 4 additional lines I had expected earlier. I'm writing to the socket with: (socket writeStream) nextPutAll: 'EHLO txtmail' , String lineDelimiter; flush. input := self readAllSocketInput: socket. where readAllSocketInput is: readAllSocketInput: readSocket | remaining | remaining := String writeStream. [socket hasInput] whileTrue: [remaining nextPutAll: (readSocket readStream upTo: Character lf asInteger) asString]. ^remaining contents It looks like the CDO stuff will suffice anyway - certainly easier than fighting these sockets if I don't need to. |
[hidden email] wrote:
> [socket hasInput] whileTrue: I think that's your problem. #hasInput is a private method which invokes the Win32 API directly, what it'll tell you is whether there is any input waiting in the OS's buffers. Since the OS notifies Dolphin (asychronously) when there is data available, and Dolphin then pulls that data into its own stream buffer, #hasInput can never tell you anything reliable or useful. What you have to do is loop reading (via the normal public methods) /unconditionally/ until you have reached the end of the data that you expect. If the socket has been closed unexpectedly then you'll get an exception which you have to handle. There is no way of writing any variant of a: [aStream atEnd] whileFalse: [...] loop -- that just doesn't make sense for data coming from the network. -- chris |
Free forum by Nabble | Edit this page |