Is it possible to implement an async HTTP server with Rust in NodeJS async style:
server.on('/url, function(req, resp){
// call resp.end() if you need
});
I also need to be able to implement hanging GET, i.e. when I call resp.end not immediately, but later, on some other event. I tried http-rotor but it panics if the request is not finalized.
Related
I am using bidirectional grpc between my client and server. I would like to implement async bidi on both client and server i.e., client opens a stream and starts sending arbitrary messages to server, while another thread continues receiving server responses. This example below demonstrates the server side async bidi https://groups.google.com/forum/m/#!topic/grpc-io/DuBDpK96B14.
Has anyone tried async bidi on client side?
There's a codelab for it with both client and server at https://grpc.io/docs/tutorials/async/helloasync-cpp/
Async client
To use an asynchronous client to call a remote method, you first create a channel and stub, just as you do in a synchronous client. Once you have your stub, you do the following to make an asynchronous call:
Initiate the RPC and create a handle for it. Bind the RPC to a CompletionQueue.
CompletionQueue cq;
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
Ask for the reply and final status, with a unique tag
Status status;
rpc->Finish(&reply, &status, (void*)1);
Wait for the completion queue to return the next tag. The reply and status are ready once the tag passed into the corresponding Finish() call is returned.
void* got_tag;
bool ok = false;
cq.Next(&got_tag, &ok);
if (ok && got_tag == (void*)1) {
// check reply and status
}
You can see the complete client example in greeter_async_client.cc.
For my Google Assistant/Dialogflow project, I am trying to intercept every response my firebase-functions endpoint is sending back to Dialogflow. I can easily intercept the request, but the response gets built within several functions (one function for every Intent), and I don't want to include an interceptor in every function.
Is it possible to have a middleware or is there a callback provided when a response is send out, sort of a global interceptor for every response?
I have found the following in the Docs: https://firebase.google.com/docs/functions/http-events#use_middleware_modules_with
However, I am unsure where this goes. Note that I am not using a custom express setup, but I am using the native implementation on firebase directly.
serialize() method is called on conversation right before the response is sent back, so what you can do is to extend the conversation object(based on the library you are using) and overwrite the serialize method to do whatever you need to do. don't forget to call the original serialize method and return the value in your new method.
Since you are using Dialog Flow with Firebase for your fulfilment, I am expecting you are also using actions-on-google package.
serialize() is a function which is called to generate the response. You can override this function and intercept the request and response. Try this code and thank me later. 😉
app.middleware((conv) => {
const serializeCopy = conv.serialize;
conv.serialize = () => {
const response = serializeCopy.call(conv);
console.log(conv.request, response);
return response;
};
});
Cloud Functions does not expose any sort of middleware or interceptors for HTTP requests or responses. You will have to build something yourself, probably with an Express app that you build yourself. You can host an Express app on Cloud Functions.
I wanted something similar to intercept all conversations back and forth for logging purposes. I ended up writing a function that I use to send a conversation. For eg:
const intercept = (conv, sentence) => {
//My Interceptor code
conv.ask(sentence)
}
Now anytime I want to send a response, I would use:
intercept(conv, "Speak this")
Router.current().route.getName() is returning an error when I use it in a method call (server side method). I thought they say Iron-Router is supposed to work both client and server side. The error I get is
Error invoking Method 'mySeverSideMethod': Internal server error [500]
Please help.
You are half way right, the router works on both client and server. However the server-side implementation is meant for server side routes (eg. REST endpoints). There is no "state" sharing between client/server with iron:router (when invoked inside methods), so Router.current().route.getName() is going to throw you this error, because Router.current() is undefined.
Yes, iron:router can create server side routes, but that api is client only
From the docs:
Router.route('/download/:file', function () {
// NodeJS request object
var request = this.request;
// NodeJS response object
var response = this.response;
this.response.end('file download content\n');
}, {where: 'server'});
You have access to the NodeJS request object so you should be able to find what you need there, e.g. this.request.route, this.request.path.
When calling a Method, you're not going through a 'route' as defined by Iron-Router: it's a route defined by the Meteor framework. It does not care what route the client is on.
So, if you need to know from what page the client is calling the endpoint, you should pass it as a parameter to the Method.
Meteor.methods({
"myEndPoint": function(route) {
// use route here.
return //something
}
})
For example:
server/method.js
Meteor.methods({
insertPost: function(post) {
//call another method
var ret = Meteor.call('longTimeMethod', post.data); // A
// ...
}
})
Meteor doc says
If you do not pass a callback on the server, the method invocation will block until the method is complete.
since nodejs is single thread, if A costs 60 seconds, the whole server will not response to any requests during this 60s?
No, not the whole server will block, only the fiber running for this particular client. If you don't want that, then you can simply call this.unblock() before your method call, and a new fiber will be used for future method calls from that client, see http://docs.meteor.com/#/full/method_unblock.
I have a Meteor.method defined on the server side (in .js in /server) and I can call it just fine (with callback) from a client-side template script.
I want to do a similar thing but would like it all to be client side so I moved the method to a client script but the result comes back as 'undefined'.
Template.showDialog.events({
'click #clickme' : function() {
Meteor.call('foo', 'ola', function(error, result) {
alert('here');
alert(result);
});
}
});
Meteor.methods({
foo: function (myarg) {
return myarg+'CLI';
}
});
See the Meteor docs, where it is explained that methods on the client are stubs, not actual methods:
If you do define a stub, when a client invokes a server method it will also run its stub in parallel. On the client, the return value of a stub is ignored. Stubs are run for their side-effects: they are intended to simulate the result of what the server's method will do, but without waiting for the round trip delay. If a stub throws an exception it will be logged to the console.
Since the result is ignored, you're seeing undefined. Don't use methods on the client for this purpose. Just use a javascript function.
From the docs:
Calling methods on the client defines stub functions associated with server methods of the same name.
Basically, you need to define the method on the server side. It's also not clear why you'd want to define a method on the client and then call it on the client as well. Would a vanilla javascript function not do the job perfectly well?
Apologies if I've misunderstood what you're trying to achieve here.