-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to instantiate Service? #507
Comments
The wiki refers to protobuf.js 5. Using protobuf.js 6, services are instances of the service class here. You can look them up, but there is not a lot of functionality within. You can, however, get the resolved request and response types of the respective methods. var service = root.lookup("MyService");
var method = service.methods["myMethod"].resolve();
var reqType = method.resolvedRequestType;
var resType = method.resolvedResponseType;
... There has been a bit of discussion previously to support use cases like grpc out of the box, but as I am not using services myself, I'd require some suggestions. |
This commit adds the following API: var MyService = root.lookup("MyService");
// First, implement the RPC channel:
function rpc(method, requestData, callback) {
// send requestData (binary) over the network
...
// then call the callback with error, if any, and the received responseData (binary)
callback(null, responseData);
}
// Create a runtime service:
var myService = MyService.create(/* your rpc implementation */ rpc, /* requestDelimited? */ true, /* responseDelimited? */ true);
// Call its methods (uses your RPC channel)
myService.MyMethod({ awesomeField: "awesomeText" }, function(err, responseMessage) {
...
}); |
Feel free to reopen if there are still any issues or if you have a suggestion on how this should be implemented. |
@dcodeIO thanks Daniel! Works like a charm! One quick question, maybe I found a bug...: So in RPC I do this: function rpc(method, requestData, callback) {
var RequestType = root.lookup('RequestType');
// CRASH in ReaderPrototype.skip on throw indexOutOfRange(this);
var request = RequestType.decode(requestData); Trying to debug: $ requestData.toString()
"\u0000" I know it's silly that my messages are empty at the moment, but I guess it shouldn't crash anyway and it's good for QA:
|
So, your messages are length delimited, right? Did you specify that to Service.create? var myService = MyService.create(/* your rpc implementation */ rpc, /* requestDelimited? */ true, /* responseDelimited? */ true); Otherwise the length-bytes will be interpreted as message contents and throwing there is actually what it should do. |
Well I am not sure whether message without any fields is delimited or not. But if I create RPC with |
Above you mentioned that, in one of your messages, there was a single zero byte:
That's why I assumed that it is a length-delimited empty message which of course throws if interpreted as a non-delimited message. |
Yeah strange, that's how I call the method: service.addMailbox(RequestType.create(), function (err, res) {
console.log(err);
}); Not sure where 0-byte comes from. RequestType as is without any fields. Update: if I specify that request is length delimited then rpc receives a buffer with one 0-byte, otherwise 0-length buffer is received. |
Strange. in fact. The code encoding to a buffer is here: https://github.com/dcodeIO/protobuf.js/blob/master/src/service.js#L159 If shouldn't generate the zero byte, except if there is something true-ish specified for |
This is the source code if it helps ( bare bones) #!/usr/bin/env node
var ProtoBuf = require("protobufjs");
ProtoBuf.load('mailservice.proto', function (err, root) {
var MailService = root.lookup('MailService');
var RequestType = root.lookup('RequestType');
var ResponseType = root.lookup('ResponseType');
function rpc(method, requestData, callback) {
var request = RequestType.decode(requestData);
if(method.fullName === '.MailService.addMailbox') {
// add mailbox
var response = ResponseType.create();
callback(null, response);
} else if(method.fullName === '.MailService.removeMailbox') {
// remove mailbox
var response = ResponseType.create();
callback(null, response);
} else {
throw new Error('Not implemented.');
}
}
var service = MailService.create(rpc, true, false);
service.addMailbox(RequestType.create(), function (err, res) {
console.log(err);
});
}); mailservice.proto: syntax="proto3";
message Mailbox {
required string name = 1;
repeated Mail messages = 2;
}
message Mail {
string subject = 1;
string body = 2;
}
message RequestType {}
message ResponseType {}
service MailService {
rpc addMailbox(RequestType) returns (ResponseType);
rpc removeMailbox(RequestType) returns (ResponseType);
} |
Hey, quick question: so with Protobuf.js I can create RPC server in Node.js and that's pretty clear, however, how do I define an RPC client? Do I have to funnel data to remote RPC and pass back results somehow? I use ZeroMQ as transport to pass data between processes. As I understand there is no Rpc channel/controller for that so I have to implement all of that myself? i.e: message RpcCall {
string method = 1;
bytes message = 2;
} |
There is an example in the README. There is also a streaming rpc example here. It basically works the same way on a client or a server. You just have to implement |
@dcodeIO thanks. I figured that it works on network level so it was easy to wire up everything! |
Hi,
I am following the example at https://github.com/dcodeIO/protobuf.js/wiki/Services and creating my RPC.
Everything seems fine but I cannot create a new instance of Service. it says:
The text was updated successfully, but these errors were encountered: