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