Node Buffer 2 – Customize Binary Protocol

Node in Practice 第三章 – Buffer – 定制通讯协议 Demo。


参考:

  1. Alex Young, Marc Harter. Node in Practice. 2015
  2. https://tools.ietf.org/html/rfc6713
;const FakeDB = (function () {
  'use strict';

  const zlib = require('zlib');

  /**
   * DB bitmask:
   * 1        2        4        8        16       32       64       128
   * -----------------------------------------------------------------------
   * 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000
   */
  const self = {
    // N elements
    get N () { return 8; },
    // zlib magic num (rfc6713)
    get MAGIC_NUM () { return 0x78; },
  };

  const $ = function () {
    self.database = new Array(self.N).fill().map(() => []);
    self.bitmasks = new Array(self.N).fill().map((v, i) => 1 << i);

    self._store = __store.bind(this);

    this.__defineGetter__('database', () => self.database);
  }

  $.prototype.store = function (buf) {
    const db = buf[0];
    const key = buf.readUInt8(1);

    return new Promise((resolve, reject) => {
      if (buf[2] === self.MAGIC_NUM) {
        // inflate zip
        zlib.inflate(buf.slice(2), (err, inflatedBuf) => {
          if (err) return reject(err);

          const data = inflatedBuf.toString();
          self._store({db, key, data});
          resolve(self.database);
        });
      } else {
        process.nextTick(() => {
          const data = buf.slice(2);
          self._store({db, key, data});
          resolve(self.database);
        });
      }
    });
  };

  function __store ({db, key, data}) {
    // store in db
    self.bitmasks.forEach((bitmask, index) => {
      if ((db & bitmask) === bitmask)
        self.database[index][key] = data;
    });
  }

  return $;
}());

// Use FakeDB
;(function () {
  const zlib = require('zlib');

  const fakeDB = new FakeDB();

  const header = Buffer.alloc(2, `${
    String.fromCharCode.call(null, 8) // No.3
  }${
    String.fromCharCode.call(null, 0) // Key 0
  }`);

  zlib.deflate('my message', (err, deflatedBuf) => {
    if (err) return console.error(err);

    const message = Buffer.concat.call(null, [header, deflatedBuf]);

    fakeDB.store(message)
      .then(data => console.log(data))
      .catch(reason => console.error(reason));
  });
}());

作者: V

Web Dev

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google photo

您的留言將使用 Google 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s