packet.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. 'use strict';
  2. const Constant = require('../const');
  3. const byteBuffer = require('./byte_buffer');
  4. const Long = require('long');
  5. /**
  6. * 0 1 2 4 12
  7. * +---------+---------+-------------------+-------------------------------------------------------------------------------+
  8. * | version | req/res | reserved | request id |
  9. * +---------------------------------------+---------------------------------------+---------------------------------------+
  10. * | timeout | connection object length | application object length |
  11. * +---------------------------------------+-------------------+-------------------+---------------------------------------+
  12. * | conn object (JSON format) ... | app object |
  13. * +-----------------------------------------------------------+ |
  14. * | ... |
  15. * +-----------------------------------------------------------------------------------------------------------------------+
  16. *
  17. * packet protocol:
  18. * (1B): protocol version
  19. * (1B): req/res
  20. * (2B): reserved
  21. * (8B): request id
  22. * (4B): timeout
  23. * (4B): connection object length
  24. * (4B): application object length
  25. * --------------------------------
  26. * conn object (JSON format)
  27. * --------------------------------
  28. * app object
  29. */
  30. class Packet {
  31. /**
  32. * cluster protocol packet
  33. *
  34. * @param {Object} options
  35. * - @param {Number} id - The identifier
  36. * - @param {Number} type - req/res
  37. * - @param {Number} timeout - The timeout
  38. * - @param {Object} connObj - connection object
  39. * - @param {Buffer} data - app data
  40. * @constructor
  41. */
  42. constructor(options) {
  43. this.id = options.id;
  44. this.type = options.type;
  45. this.timeout = options.timeout;
  46. this.connObj = options.connObj;
  47. this.data = typeof options.data === 'string' ? Buffer.from(options.data) : options.data;
  48. }
  49. get isResponse() {
  50. return this.type === Constant.RESPONSE;
  51. }
  52. encode() {
  53. const header = Buffer.from([ Constant.VERSION, this.type, 0, 0 ]);
  54. const connBuf = Buffer.from(JSON.stringify(this.connObj));
  55. const appLen = this.data ? this.data.length : 0;
  56. byteBuffer.reset();
  57. byteBuffer.put(header);
  58. byteBuffer.putLong(this.id);
  59. byteBuffer.putInt(this.timeout);
  60. byteBuffer.putInt(connBuf.length);
  61. byteBuffer.putInt(appLen);
  62. byteBuffer.put(connBuf);
  63. if (appLen) {
  64. byteBuffer.put(this.data);
  65. }
  66. return byteBuffer.array();
  67. }
  68. static decode(buf) {
  69. const isResponse = buf[1] === Constant.RESPONSE;
  70. const id = new Long(
  71. buf.readInt32BE(8), // low, high
  72. buf.readInt32BE(4)
  73. ).toNumber();
  74. const timeout = buf.readInt32BE(12);
  75. const connLength = buf.readInt32BE(16);
  76. const appLength = buf.readInt32BE(20);
  77. const connBuf = Buffer.alloc(connLength);
  78. buf.copy(connBuf, 0, 24, 24 + connLength);
  79. const connObj = JSON.parse(connBuf);
  80. let data;
  81. if (appLength) {
  82. data = Buffer.alloc(appLength);
  83. buf.copy(data, 0, 24 + connLength, 24 + connLength + appLength);
  84. }
  85. return {
  86. id,
  87. isResponse,
  88. timeout,
  89. connObj,
  90. data,
  91. };
  92. }
  93. }
  94. module.exports = Packet;