作者你好, 自己对 jieba.el
的 simple-jieba-server.js
和 stdio-jrpc.js
比较感兴趣. 知道作者是通过 json-rpc
协议来进行调用 nodejieba
的.
所以自己在 terminal
上手动调用 simple-jieba-server.js
进行初步试验.
➜ echo '{"jsonrpc":"2.0", "id":74, "method":"split", "params":["今天天气很好"]}' | node simple-jieba-server.js
{"jsonrpc":"2.0","id":74,"result":["今天天气","很","好"]}SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at RPCConnection._receiveRaw (/Users/c/jieba.el/stdio-jrpc.js:66:25)
at Socket.<anonymous> (/Users/c/jieba.el/stdio-jrpc.js:55:18)
at Socket.emit (events.js:200:13)
at emitReadable_ (_stream_readable.js:558:12)
at onEofChunk (_stream_readable.js:536:5)
at readableAddChunk (_stream_readable.js:243:5)
at Socket.Readable.push (_stream_readable.js:210:10)
at Pipe.onStreamRead (internal/stream_base_commons.js:197:12)
{"jsonrpc":"2.0","id":null,"error":{"code":-32700,"message":"Error during parsing."}}%
可以看到 今天天气很好
已经被成功的分词了.
但是为什么还是会出现 JSON.parse
的错误呢?
作者在 this._receiveRaw
中对接受到的输入进行 JSON 解析.
我看了 stdio-jrpc.js
代码中 this._receiveRaw
是在 RPCConnection
类的构造器中调用的, 第一次调用成功的分词了, 说明第一次成功的解析了 JSON, 但是为什么会出现第二次的调用, 进而导致出现解析的 JSON 是空的, 最终导致抛出异常?
class RPCConnection {
constructor () {
this._methodTable = new Map();
this._currentHandlingId = null;
process.stdin.setEncoding("utf-8");
process.stdin.on("readable", () => {
let data = "";
let chunk;
while (true) {
chunk = process.stdin.read();
if (chunk === null) {
break;
} else {
data += chunk;
}
}
this._receiveRaw(data);
});
}
_sendRaw (rawMsg) {
process.stdout.write(rawMsg);
}
_receiveRaw (rawMsg) {
let json;
try {
json = JSON.parse(rawMsg);
} catch (e) {
console.error(e);
this.sendError(RPCErrors.ParseError());
}
if (json != null) {
let { jsonrpc, id, method, params } = json;
this._currentHandlingId = id;
if (jsonrpc !== "2.0") {
this.sendError(RPCErrors.InvalidRequest());
} else if (!this._methodTable.has(method)) {
this.sendError(RPCErrors.MethodNotFound());
} else {
let m = this._methodTable.get(method);
m(params);
}
}
// Reset id
this._currentHandlingId = null;
}