java 发表于 2017-12-28 16:14:48

wildduck代码分析

本帖最后由 java 于 2018-1-2 17:22 编辑

https://github.com/hechengjin/wildduck-webmail

---------------IMAP-----------------------
server.js
require('./worker.js');
worker.js
const imap = require('./imap');

imap.js
const onStore = require('./lib/handlers/on-store');
const onExpunge = require('./lib/handlers/on-expunge');


start()
indexer = new Indexer({
    database: db.database
});

// setup notification system for updates
notifier = new ImapNotifier({
    database: db.database,
    redis: db.redis
});

messageHandler = new MessageHandler({
    database: db.database,
    redis: db.redis,
    gridfs: db.gridfs,
    attachments: config.attachments
});

createInterface()
const server = new IMAPServer(serverOptions);
server.indexer = indexer;
server.notifier = notifier;

server.onStore = onStore(server);
server.onExpunge = onExpunge(server, messageHandler);

server.listen(ifaceOptions.port, ifaceOptions.host, () => {..}   //Acceptor

//Acceptor
./wildduck/imap-core/lib/imap-server.js/////////////////////////////////////
this.server = net.createServer(this.options, socket =>
                this._handleProxy(socket, (err, socketOptions) => {
                  if (err) {
                        // ignore, should not happen
                  }
                  this.connect(socket, socketOptions);//处理新连接
                })
            );

            connect(socket, socketOptions) {
                connection.on('error', this._onError.bind(this));
                connection.init();
            }

//./wildduck/imap-core/lib/imap-connection.js   /////////////////////////////////////
class IMAPConnection extends EventEmitter {
//构造函数
this._server = server;
this._socket = socket;
this.writeStream = new IMAPComposer({
      connection: this
});
this.writeStream.pipe(this._socket);
// Parser instance for the incoming stream
this._parser = new IMAPStream();

// Set handler for incoming commands
this._parser.oncommand = this._onCommand.bind(this);

//初始化函数 init()
this._socket.pipe(this._parser);
this.session = {id: this.id, selected: this.selected, ....}

//命令行命令处理
_onCommand(command, callback) {
this._currentCommand = currentCommand = new IMAPCommand(this);
currentCommand.end(command, callback);
...
}
}

//./wildduck/imap-core/lib/imap-command.js /////////////////////////////////////
const commands = new Map([
...
['UID STORE', require('./commands/uid-store')],
['EXPUNGE', require('./commands/expunge')],
...
]);

class IMAPCommand {
end(command, callback) {
      let handler = commands.get(this.command); //查询命令处理handler
      handler.handler.call(...) //调用handler处理
}
...}

//./wildduck/imap-core/lib/commands/expunge.js   /////////////////////////////////////
handler(command, callback) {
      //调用上层设置的回调函数
      this._server.onExpunge(
            this.selected.mailbox,
            {
                isUid: false
            },
            this.session,
            (err, success) => {
                if (err) {
                  return callback(err);
                }

                callback(null, {
                  response: success === true ? 'OK' : 'NO',
                  code: typeof success === 'string' ? success.toUpperCase() : false
                });
            }
      );
...}

//上层对命令的处理 imap.js
const onExpunge = require('./lib/handlers/on-expunge');
server.onExpunge = onExpunge(serveopenssl s_client -connect 127.0.0.1:9110r, messageHandler);

//./wildduck/lib/handlers/on-expunge.js
module.exports = (server, messageHandler) => (mailbox, update, session, callback) => {
....
}




java 发表于 2017-12-29 11:58:41

测试用例跑法
mocha ./imap-core/test/my-test.js--config=./config/test.toml

java 发表于 2018-1-2 15:51:21

本帖最后由 java 于 2018-1-3 11:42 编辑

网络IO模型
https://nodejs.org/dist/latest-v8.x/docs/api/net.html
页: [1]
查看完整版本: wildduck代码分析