How do I implement a read / write client such as a POP3 client in node.js
I'm not well versed in the art of node.js, so I'm not sure how to go about this: I want to write a client that can connect to a POP3 server and write to the server, and react to what ever the server sends back.
- Open connection to server
- Read server welcome
- Send "USER some_user@domain.com"
- Check for "+OK User Accepted"
- Send "PASS mypassword"
- Check for "+OK Pass Accepted"
If the server replies with anything but OK, trigger an error event.
What I have so far:
var net = require('net')
, sys = require('sys')
;
conn = net.createConnection(110, 'mail.somehost.com');
conn.setEncoding("utf8");
//1. Open Connection
conn.on('connect', function() {
//2. Read welcome
conn.once('data', function(data) {
conn.pause();
console.log('Server Welcome: ' + data);
//4. Prepare to get response from server
conn.once('data', function(data) {
console.log('USER Response: ' + data);
});
//3. Send USER
conn.write('USER some_user@domain.开发者_如何学JAVAcom' + "\n");
conn.resume();
})
});
Will the conn.pause, handle return, conn.once, conn.write, conn.resume sequence work for all of the interaction?
Update
As already stated, you should go with the following approach:
Write a basic parser for the protocol, you might end up with
data
only having the first 5 bytes of a line, you need to handle this without tons of duplicationThe parser buffers the data and dispatches it to the different events
It will be fairly easy to add a
pause
function to the parser, if you really need thatUsing the dispatch model in combination with a state variable your code will:
A. Look way cleaner
B. Be a lot easier to maintain
C. You can, for example, send theUSER Response
and then let theOK
handler method decide what it does based on the current stateThis will overall reduce code duplication. Also what you're doing now is known as Arrow Programming (all your ifs/callbacks form an arrow)
Old Answers
The server waits for more data to come in, simply put, you need to end the line you send with CLRF
aka. \r\n
.
conn.write('USER some_user@domain.com\r\n');
Guess you should give the spec a read:
https://www.rfc-editor.org/rfc/rfc1939
Also, your .once
approach will very soon, get very complicated to maintain. I would instead use the normal .on
event handling and have a state for the communication progress.
var state = 'CONNECT';
conn.on('connect', function() {
conn.on('data', function(data) {
// actually you should make sure that you got the COMPLETE message here
// it may be the case that you only got half of it so check for CLRF
// you should also buffer stuff after an incoming CLRF
// best thing would be that you write a parser first that then dispatches the messages
// to specific handlers
switch (state) {
case 'CONNECT':
// blabla
state = 'GETRESPONSE';
break;
case 'GETRESPONSE':
// response
break;
case default:
break;
}
})
});
Of course how you exactly implement this is left to you, you could just as well map the current state to a table of functions/methods which get that data and do something with it.
精彩评论