ali-ons-sdk
Version:
Aliyun Open Notification Service Client
176 lines (151 loc) • 4.01 kB
JavaScript
'use strict';
/* eslint no-bitwise: 0*/
const bytes = require('bytes');
const is = require('is-type-of');
const ByteBuffer = require('byte');
const OpaqueGenerator = require('./opaque_generator');
const REQUEST_COMMAND = 'REQUEST_COMMAND';
const RESPONSE_COMMAND = 'RESPONSE_COMMAND';
// 0, REQUEST_COMMAND
// 1, RESPONSE_COMMAND
const RPC_TYPE = 0;
// 0, RPC
// 1, Oneway
const RPC_ONEWAY = 1;
const buf = new ByteBuffer({ size: bytes('1m') });
class RemotingCommand {
/**
* metaq 命令
* @param {Object} options
* - code {Number} 命令代号
* - customHeader {Object} 自定义头部
* - flag {Number} 标识命令的属性
* - opaque {Number} 关联请求、响应的字段
* - remark {String}
* - extFields {Object} 扩展字段
*/
constructor(options) {
this.code = options.code;
this.customHeader = options.customHeader;
this.flag = options.flag || 0;
this.opaque = options.opaque || OpaqueGenerator.getNextOpaque();
this.remark = options.remark;
this.extFields = options.extFields || {};
this.body = null;
}
get language() {
return 'JAVA';
}
get version() {
return 78;
}
get type() {
return this.isResponseType ? RESPONSE_COMMAND : REQUEST_COMMAND;
}
get isResponseType() {
const bits = 1 << RPC_TYPE;
return (this.flag & bits) === bits;
}
get isOnewayRPC() {
const bits = 1 << RPC_ONEWAY;
return (this.flag & bits) === bits;
}
markResponseType() {
const bits = 1 << RPC_TYPE;
this.flag |= bits;
}
markOnewayRPC() {
const bits = 1 << RPC_ONEWAY;
this.flag |= bits;
}
makeCustomHeaderToNet() {
const customHeader = this.customHeader;
if (!customHeader) {
return;
}
this.extFields = this.extFields || {};
for (const key in customHeader) {
const field = customHeader[key];
if (is.nullOrUndefined(field) || is.function(field)) {
continue;
}
this.extFields[key] = field;
}
}
decodeCommandCustomHeader() {
return JSON.parse(JSON.stringify(this.extFields)); // 深拷贝
}
buildHeader() {
this.makeCustomHeaderToNet();
return new Buffer(JSON.stringify({
code: this.code,
language: this.language,
opaque: this.opaque,
flag: this.flag,
version: this.version,
remark: this.remark,
extFields: this.extFields,
}), 'utf8');
}
encode() {
buf.reset();
let length = 4;
const headerData = this.buildHeader();
length += headerData.length;
if (this.body) {
length += this.body.length;
}
buf.putInt(length);
buf.putInt(headerData.length);
buf.put(headerData);
if (this.body) {
buf.put(this.body);
}
return buf.copy();
}
/**
* 创建 request 命令
* @param {Number} code - 命令代号
* @param {Object} customHeader -
* @return {RemotingCommand} command
*/
static createRequestCommand(code, customHeader) {
return new RemotingCommand({
code,
customHeader,
});
}
/**
* 创建 request 命令
* @param {Number} code - 命令代号
* @param {Number} opaque -
* @param {String} remark -
* @return {RemotingCommand} command
*/
static createResponseCommand(code, opaque, remark) {
const command = new RemotingCommand({
code,
opaque,
remark: remark || 'not set any response code',
});
command.markResponseType();
return command;
}
/**
* 反序列化报文
* @param {Buffer} packet -
* @return {RemotingCommand} command
*/
static decode(packet) {
const customHeaderLength = packet.readInt32BE(4);
const customHeaderData = packet.slice(8, 8 + customHeaderLength);
let body;
if (packet.length - 8 - customHeaderLength > 0) {
body = packet.slice(8 + customHeaderLength);
}
const command = new RemotingCommand(JSON.parse(customHeaderData));
command.body = body;
return command;
}
}
module.exports = RemotingCommand;