如何在node.js中实现读/写客户端,如POP3客户端

时间:2010-12-15 11:40:22

标签: node.js

我不熟悉node.js的艺术,所以我不确定如何解决这个问题:我想编写一个可以连接到POP3服务器并写入服务器的客户端,并做出反应到服务器发回的内容。

  1. 打开与服务器的连接
  2. 阅读服务器欢迎
  3. 发送“USER some_user@domain.com”
  4. 检查“+ OK用户已接受”
  5. 发送“PASS mypassword”
  6. 检查“+ OK Pass Pass Accepted”
  7. 如果服务器回复了除OK之外的任何内容,则触发错误事件。

    到目前为止我所拥有的:

    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.com' + "\n");
            conn.resume();
        })
    
    });
    

    conn.pause,handle return,conn.once,conn.write,conn.resume序列是否适用于所有交互?

1 个答案:

答案 0 :(得分:1)

更新

如前所述,您应该采用以下方法:

  1. 为协议编写一个基本的解析器,最后只有data只有一行的前5个字节,你需要处理这个没有大量的重复
  2. 解析器缓冲数据并将其分派给不同的事件
  3. 如果您确实需要pause函数,那么将USER Response函数添加到解析器中相当容易
  4. 将调度模型与状态变量结合使用,您的代码将:

    一个。看起来更清洁了 B.更容易维护 C.例如,您可以发送OK,然后让CLRF处理程序方法根据当前状态决定它的作用

  5. 这将全面减少代码重复。你现在所做的也被称为箭头编程(你所有的ifs / callbacks形成一个箭头)

  6. 旧答案

    服务器等待更多数据进来,简单地说,您需要结束使用\r\n aka发送的行。 conn.write('USER some_user@domain.com\r\n');

    .once

    猜猜你应该给这个规格读一读:
    http://tools.ietf.org/html/rfc1939

    此外,您的.on方法很快就会很难维护。我会使用正常的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; } }) }); 事件处理,并具有通信进度的状态。

    {{1}}

    当然,你如何完全实现这一点,你也可以将当前状态映射到一个函数/方法表中,这些函数/方法可以获取数据并对其进行处理。