-
Notifications
You must be signed in to change notification settings - Fork 132
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
Decoding protobuf response #584
Comments
gRPC-web uses a message framing. It's superficially documented here. It's just length delimited, with space for a couple of flags. You can take a look at the transport implementation here if you want to roll your own:
|
Is the first part of that function just waiting for a request and then creates an Uint8Array from it, right? function readGrpcWebResponseBody(uintArr, onFrame) {
let byteQueue = uintArr;
while (byteQueue.length >= 5 && byteQueue[0] === GrpcWebFrame.DATA) {
let msgLen = 0;
for (let i = 1; i < 5; i++) {
msgLen = (msgLen << 8) + byteQueue[i];
}
if (byteQueue.length - 5 >= msgLen) {
// we have the entire message
onFrame(GrpcWebFrame.DATA, byteQueue.subarray(5, 5 + msgLen));
byteQueue = byteQueue.subarray(5 + msgLen);
} else {
break;
}
}
} What i don't understand is how onFrame works, because it takes the "O" from the method of the response and uses .fromBinary() passing the actual response as a parameter? Sorry for the misunderstanding but i don't really know that much about this and i can't actually wrap my mind around how this works. PS.: How the "grpc-web-dev-tools" works is that it adds interceptors to all the clients and decodes or captures the responses from them. I don't really want to do that. What i'm doing right now is just capture the request responses when they finish and i don't really know if the information i got from the response is enought to actually decode the messages. |
gRPC-web uses a message framing. The function splits an incoming stream of binary data into individual frames.
To split the frames, yes. To parse protobuf messages from binary, no. See https://protobuf.dev/programming-guides/encoding/ |
You can get the "grpc-web-dev-tools" extension working with protobuf-ts by adding this interceptor to your grpc-web transport: import type { RpcInterceptor } from '@protobuf-ts/runtime-rpc';
import { RpcError } from '@protobuf-ts/runtime-rpc';
const type = '__GRPCWEB_DEVTOOLS__';
export const grpcWebDevToolsInterceptor: RpcInterceptor = {
interceptUnary(next, method, input, options) {
const res = next(method, input, options);
// @ts-ignore
if (window.__GRPCWEB_DEVTOOLS__) {
const methodType = 'unary';
const m = `${method.service.typeName}/${method.name}`;
const request = method.I.toJson(res.request);
void res.then((value) => {
window.postMessage({
type,
method: m,
methodType,
request,
response: method.O.toJson(value.response),
});
}).catch((e) => {
if (e instanceof RpcError) {
window.postMessage({
type,
method: m,
methodType,
request,
error: {
code: e.code,
message: e.message,
},
});
}
});
}
return res;
},
interceptServerStreaming(next, method, input, options) {
const res = next(method, input, options);
// @ts-ignore
if (window.__GRPCWEB_DEVTOOLS__) {
const m = `${method.service.typeName}/${method.name}`;
const methodType = 'server_streaming';
window.postMessage({
type,
method: m,
methodType,
request: method.I.toJson(res.request),
});
res.responses.onMessage((value) => {
window.postMessage({
type,
method: m,
methodType,
response: method.O.toJson(value),
});
});
res.responses.onError((e) => {
if (e instanceof RpcError) {
window.postMessage({
type,
method: m,
methodType,
error: {
code: e.code,
message: e.message,
},
});
}
});
res.responses.onComplete(() => {
window.postMessage({
type,
method: m,
methodType,
response: 'EOF',
});
});
}
return res;
},
}; |
Does this have an impact in performance? Thank you anyways! |
Only if you have the "grpc-web-dev-tools" extension enabled. |
@jcready I'm using the code you posted and is failing for stream because |
Ah, sorry about that. I believe I've fixed the code above. |
I recently switched up from protobuf-js to this library, i really liked the change and it is working fine.
The thing is that there was a chrome extension i used to check the requests being made in every client of the application, and it doesn't work with the clients generated by protobuf-ts.
I thought about making an extension myself as i didn't believe it would be that hard, and i actually was able to get the response body from all the requests from the clients i generated in a chrome extension i made, when tried decoding them from base64 to string it gives a string with non ascii characters and numbers in between the real data of the response.
This is the one of the respones i got:
When decoded gives me this:
'~ #����Test��https://www.google.com/ � �����Specs��/specifications � 9����WIP�./specifications/search?status=Work+In+Progress �'
This is what the "grcp web dev tools" gives me:
I tried in many ways but i didn't found that much information about it in the internet, so i came here to ask if anyone knows how can i decode the information in the response to a JSON or JS Object or at least a simple string?
Thanks!
The text was updated successfully, but these errors were encountered: