Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
46 changed files
with
3,221 additions
and
483 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
'use strict'; | ||
|
||
const { RpcClient } = require('sofa-rpc-node').client; | ||
const { ZookeeperRegistry } = require('sofa-rpc-node').registry; | ||
const protocol = require('..'); | ||
const logger = console; | ||
|
||
// 1. 创建 zk 注册中心客户端 | ||
const registry = new ZookeeperRegistry({ | ||
logger, | ||
address: '127.0.0.1:2181', | ||
}); | ||
|
||
async function invoke() { | ||
// 2. 创建 RPC Client 实例 | ||
const client = new RpcClient({ | ||
logger, | ||
registry, | ||
protocol, | ||
}); | ||
// 3. 创建服务的 consumer | ||
const consumer = client.createConsumer({ | ||
interfaceName: 'com.nodejs.test.TestService', | ||
}); | ||
// 4. 等待 consumer ready(从注册中心订阅服务列表...) | ||
await consumer.ready(); | ||
|
||
// 5. 执行泛化调用 | ||
const result = await consumer.invoke('plus', [1, 2], { responseTimeout: 3000 }); | ||
console.log('1 + 2 = ' + result); | ||
} | ||
|
||
invoke().catch(console.error); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
'use strict'; | ||
|
||
const { RpcServer } = require('sofa-rpc-node').server; | ||
const { ZookeeperRegistry } = require('sofa-rpc-node').registry; | ||
const protocol = require('..'); | ||
|
||
const logger = console; | ||
|
||
// 1. 创建 zk 注册中心客户端 | ||
const registry = new ZookeeperRegistry({ | ||
logger, | ||
address: '127.0.0.1:2181', // 需要本地启动一个 zkServer | ||
}); | ||
|
||
// 2. 创建 RPC Server 实例 | ||
const server = new RpcServer({ | ||
logger, | ||
registry, // 传入注册中心客户端 | ||
port: 12200, | ||
protocol, | ||
}); | ||
|
||
// 3. 添加服务 | ||
server.addService({ | ||
interfaceName: 'com.nodejs.test.TestService', | ||
}, { | ||
async plus(a, b) { | ||
return a + b; | ||
}, | ||
}); | ||
|
||
// 4. 启动 Server 并发布服务 | ||
server.start() | ||
.then(() => { | ||
server.publish(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,67 +1,61 @@ | ||
'use strict'; | ||
|
||
const is = require('is-type-of'); | ||
const assert = require('assert'); | ||
const utils = require('./utils'); | ||
const urlparse = require('url').parse; | ||
const protocol = require('./protocol'); | ||
const Writable = require('stream').Writable; | ||
|
||
// 协议实现 | ||
const protocolMap = { | ||
dubbo: require('./protocol/dubbo'), | ||
exchange: require('./protocol/dubbo'), | ||
}; | ||
const HEADER_LENGTH = 16; | ||
|
||
class DubboDecoder extends Writable { | ||
constructor(options) { | ||
assert(options && is.string(options.url), '[dubbo-remoting] options.url is required'); | ||
constructor(options = {}) { | ||
super(options); | ||
this._buf = null; | ||
this._url = urlparse(options.url, true); | ||
const proto = this._url.protocol.replace(/:?$/, ''); // trim tail ":" | ||
this._protocol = protocolMap[proto]; | ||
assert(this._protocol, `[dubbo-remoting] unsupport protocol => ${proto}`); | ||
} | ||
|
||
/** | ||
* 根据 url 返回匹配的协议 | ||
* | ||
* @property {Object} DubboDecoder#protocol | ||
*/ | ||
get protocol() { | ||
return this._protocol; | ||
this.options = options; | ||
} | ||
|
||
_write(chunk, encoding, callback) { | ||
// merge old & new bytes | ||
this._buf = this._buf ? utils.concatBuffer(this._buf, chunk) : chunk; | ||
// 合并 buf 中的数据 | ||
this._buf = this._buf ? Buffer.concat([ this._buf, chunk ]) : chunk; | ||
try { | ||
let unfinish = false; | ||
do { | ||
unfinish = this._decode(); | ||
} while (unfinish); | ||
callback(); | ||
} catch (err) { | ||
err.name = 'DubboDecodeError'; | ||
err.data = this._buf ? this._buf.toString('base64') : ''; | ||
callback(err); | ||
} | ||
} | ||
|
||
_decode() { | ||
const ret = this.protocol.decode(this._buf); | ||
if (ret) { | ||
// 这里异步化是为了避免 listeners 业务报错影响到 decoder | ||
process.nextTick(() => { this.emit('packet', ret.packet); }); | ||
const bufLength = this._buf.length; | ||
|
||
const bufSize = this._buf.length; | ||
const rest = bufSize - ret.total; | ||
if (rest > 0) { | ||
this._buf = this._buf.slice(ret.total); | ||
return true; | ||
} | ||
this._buf = null; | ||
if (bufLength < HEADER_LENGTH) { | ||
return false; | ||
} | ||
const bodyLen = this._buf.readInt32BE(12); | ||
const packetLength = bodyLen + HEADER_LENGTH; | ||
if (packetLength === 0 || bufLength < packetLength) { | ||
return false; | ||
} | ||
const packet = this._buf.slice(0, packetLength); | ||
// 调用反序列化方法获取对象 | ||
const obj = protocol.decode(packet, this.options); | ||
this.emit(obj.packetType, obj); | ||
const restLen = bufLength - packetLength; | ||
if (restLen) { | ||
this._buf = this._buf.slice(packetLength); | ||
return true; | ||
} | ||
this._buf = null; | ||
return false; | ||
} | ||
|
||
_destroy() { | ||
this._buf = null; | ||
this.emit('close'); | ||
} | ||
} | ||
|
||
module.exports = DubboDecoder; |
Oops, something went wrong.