How to set timeout of grpc client in node.js - javascript

I'm referring to the following example of node-grpc client:
https://github.com/grpc/grpc/blob/master/examples/node/dynamic_codegen/greeter_client.js
//create a client
var client = new hello_proto.Greeter('localhost:50051',
grpc.credentials.createInsecure());
//issue the call
client.sayHello({name: user}, function(err, response) {
console.log('Greeting:', response.message);
});
In this call format, where do I provide the call deadline options.
Also, the jsdoc at https://grpc.io/grpc/node/ never has this kind of API calls.
Is there a good tutorial on this which covers examples like streaming rpcs, timeouts, securing the channels etc?

There's an optional argument to pass additional options between the request argument and the callback. This includes a deadline key. So you would do something like this:
client.sayHello({name: user}, {deadline: deadline}, function(err, response) {
console.log('Greeting:', response.message);
});
Deadline can either be a date object or Infinity to explicitly not have the call time out.
This is documented, sort of, as the Client#makeUnaryRequest function; just ignore the first three arguments. That mentions the optional options argument, and its type Client~CallOptions describes all of the options that can be passed there.

Related

Why modify request after request.post

Newbie question while trying to understand code created by others. Believe me I tried to understand this. Here goes..
For what reason would someone still call functions like .qs() and .json() in Request - module after we got what we need with .post() and sent the response already. They can't affect the request.post as they are called afterwards, can they?
With my skills I'm not able to understand from response module API docs (v2.22.0) what these actually do.
This is not the whole code but I tried to get the important parts here:
// When request comes to /getthisapge, make external query and return data in JSON format.
var request = require('request');
module.exports = function(app) {
app.get('/getthispage', function(req, res, next) {
var filter = {};
var query = {};
filter.category = req.query.category;
query.onBehalf = req.query.onBehalf;
request.post(URIandoptions, function(error, response, body) {
res.json(body.members)
}).qs(query).json(filter);
}
}
Without knowing exactly what the post function does (unnecessary to your question), you need to look at the order of execution.
request.post(URIandoptions, function (error, response, body){
res.json(body.members)
})
.qs(query) // ?
.json(filter); // ?
The function passed into post() does not get called at that specific moment. It is given to the post() function to do with as it pleases. This means technically that the function may never be called (depends on the api).
qs() and json() both get called upon the returning of the prior function. Usually this type of api means the following:
call post(), passing in a function to be run on completion
call qs() to setup the query details
call json() to tell the post function how to act, which in turn executes the actual post, running the completion function after data has been retrieved.

So about requesting in node.js

Ok look at this code..
var http = require('http');
var handleRequest = function (request, response){
response.writeHead(200,{"context-type":"text/plain"});
response.end('Welcome to the node club! :)');
}
//the createServer method... creates a server WOW!
http.createServer(handleRequest).listen(8888);
console.log('The servers are running and the bacon is stopping');
It seems simple enough, the handleRequest function will create a writeHead function when the node will allow me to respond ...right? And if that is the case, I will be able to write out "Welcome to the node club" in the end method. The thing I don't understand about node is the request variable or object or whatever. In the function am I requesting the node? Or is the node requesting me to run a function? I'm not using the request variable in the function so would it still run if I left it out?
The argument to http.createServer is a function to be called on each request. The function is documented as
function (request, response) { }
request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse.
What you do in this function is up to you; it can be anything.
However, virtually all web applications end up writing an answer to the client, and that's done via the response object. Also, since an application that serves just one page is quite limited, most applications also want to get information from the HTTP request, including the path requested (something like '/questions/37265770/so-about-requesting-in-node-js', in request.path), HTTP POST parameters and the like.
Your function gets called with two arguments, the first of which is the request object, the second the response object. There is no magic involved - you seem to call magic "node", but that's just the name of the project.

Meteor method returns undefined to the client (asynchronous)

I've been working on integrating Google Recaptcha into a Meteor and AngularJS web application. Everything was smooth sailing until I had to validate the recaptcha response -- for some bizarre reason, I can't get an async response from the backend to the frontend.
I've tried a lot of different variations and have read many, many posts on SO and the internet in general, but with no luck -- so I opted to post my own question.
Here's what I'm doing:
Client:
Meteor.call('recaptcha.methods.validateRecaptcha', { 'response' : this.recaptcha.getResponse(this.id) }, function(error, result) {
// error and result are both undefined
console.log('Do something with the ' + error + ' or ' + result + '.');
}
So, I'm calling a Meteor method and passing in a callback that is run when the method is done. However, the error and result parameters are both undefined.
Server:
run: function(data) {
if (this.isSimulation) {
/*
* Client-side simulations won't have access to any of the
* Meteor.settings.private variables, so we should just stop here.
*/
return;
}
return Meteor.wrapAsync(HTTP.post)(_someUrl, _someOptions);
}
That last line is a shortened version of the sync/async structure that I've found in several Meteor guides (I also tried this version), namely:
var syncFunc = Meteor.wrapAsync(HTTP.post);
var result = syncFunc(Meteor.settings.private.grecaptcha.verifyUrl, _options);
return result;
I've also tried a version using Futures:
var Future = Npm.require( 'fibers/future' );
var future = new Future();
var callback = future.resolver();
HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options, callback);
return future.wait();
Now, the intention here is that I use Meteor.call() to call this method from the client, the client-side stub runs (to prevent simulation errors since we use private Meteor.settings variables in the real non-SO server-side code) and returns immediately (which happens), and the server hits Google's Recaptcha API (which happens and the server receives a response) before returning the result to the client (which doesn't happen -- the callback occurs but with no error/success data).
My thought is that one of two things are happening:
I'm just doing something wrong and I'm not properly sending the data back to the client.
The synchronous client stub (which returns immediately) is telling the client that the server response isn't important, so it never waits for the proper asynchronous response.
Could any of the Meteor gurus weigh in here and let me know what's going on and how to get async requests to play nicely in a Meteor application?
Thanks!
From the documentation for HTTP.call, which is the generic version of HTTP.post, it says
Optional callback. If passed, the method runs asynchronously, instead of synchronously, and calls asyncCallback. On the client, this callback is required.
So, on server, you can run it asynchronously like this
run: function(data) {
if (this.isSimulation) {
/*
* Client-side simulations won't have access to any of the
* Meteor.settings.private variables, so we should just stop here.
*/
return;
}
// No need to pass callback on server.
// Since this part is not executed on client, you can do this
// Or you can use Meteor.isClient to run it asynchronously when the call is from client.
return HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options);
}

cannot understand what callback does in a Connect module

I am reading a book about NodeJs Connect. There is this small part about basicAuth module. I know that basicAuth is now deprecated, but I cannot understand this simple code. The book says
Providing an asynchronous callback function
The final option is similar, except this time a callback is passed to
basicAuth() with three arguments defined, which enables the use of
asynchronous lookups. This is useful when authenticating from a file
on disk, or when querying from a database.
Listing 7.7. A Connect basicAuth middleware component doing
asynchronous lookups
And no other information. Thats the whole part about having a callback in the basicAuth
So, code gets the username and the password. Then hypothetical object User has a method authendicate that checks if this user actually exists. And when its finished, calls the gotUser function. gotUser contains either a returned error (=no user found with that username/password) or a returned user object (a user found with that username/password). Am I right?
gotUser checks if there is an error. If there is, returns and calls callback with an error argument. So wait, what will callback do at this point? Its not defined anywhere. Will it pass the error to an error handler function? And how?
If there is not an error, gotUser calls callback again with null(= no error) and user. Once again, what will callback do? Why pass the returned user to the callback and not grab its name, mail, age etc etc and use them on a session or fill the innerHTML of a tag or whatever?
Thanks
So wait, what will callback do at this point? Its not defined anywhere.
The value of callback is defined by the basicAuth middleware.
You can find its definition within the basic-auth-connect module, used by connect, in the module's index.js:
callback(user, pass, function(err, user){
if (err || !user) return unauthorized(res, realm);
req.user = req.remoteUser = user;
next();
});
When gotUser() invokes callback(...), it's call the function(err, user){...} from the above snippet, passing the err and/or user along to be used.
And, how they're used, in the two scenarios you were wondering about...
gotUser checks if there is an error. If there is, returns and calls callback with an error argument. So wait, what will callback do at this point?
If there is not an error, gotUser calls callback again with null(= no error) and user. Once again, what will callback do?
The if (err || !user) condition will pass for both (one has an error, the other is lacking a user). It then considers the request unauthorized and will end the response immediately.
function unauthorized(res, realm) {
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
res.end('Unauthorized');
};
Why pass the returned user to the callback and not grab its name, mail, age etc etc and use them on a session or fill the innerHTML of a tag or whatever?
The middleware is applying separation of concerns, keeping itself as small and concise as possible. It's goal is just to determine a req.user and validate it.
When it's done that successfully, other middleware in the application's queue will be able to reference the user that was found. This can includes using it to render markup from a view:
// determine the user
app.use(connect.basicAuth(...));
// now make use of it
app.use(function (req, res, next) {
viewEngine.render('view', { user: req.user }, function (err, result) {
if (err) return next(err);
res.setHeader('Content-Type', 'text/html');
res.end(result);
});
});
Note: This is generalized and won't run as-is. You'll need to find and setup a view engine of your choice and substitute that into the snippet.
Also, side note on...
fill the innerHTML of a tag
Though Node.js is executing JavaScript, it's doing so within its own environment, completely detached from any browsers. It's not possible to interact directly with the DOM currently seen by the user.
There are a couple of different things going on. For one, app.use expect a function that will be called with req, res, and next. When you run connect.basicAuth, it runs this method.
Since this is a middleware method, this method will run every time a route that was defined after this method is hit.
The second thing that is going on is connect.basicAuth is a function that will be called with username, password, and a callback method. Callback is something that connect.basicAuth provides.
If you return callback(err), it will send a 401 Not Authorized back to the client. If you return callback(null, user), it will continue until either the next middleware function, or the appropriate route.

Read buffer object in node.js

I'm trying to get html page through this node module called Wreck
It should be very easy to get data but I'm unable to get them
'use strict';
var Wreck = require('wreck');
var url = 'http://www.google.it';
var callback = function(err, response, payload){
Wreck.read(response, null, function(err, body){
//here print out the html page
});
};
Wreck.get(url, callback);
Here above a simple script just a copy from the readme of the developer. according to the documentation body should return a buffer object but how can I read inside a body object? I have read to use toJSON or toString() but I don't get any result
...but I don't get any result
You ARE getting a result, an empty Buffer, but it's not want you want, probably.
The fact is: you are using the read method wrong, passing it inside a callback to the get method. The methods get, post, put and delete already call read internaly and return the readable Buffer for you, in a callback. Take a look at the get doc:
get(uri, [options], callback)
Convenience method for GET operations.
uri - The URI of the requested resource.
options - Optional config object containing settings for both request and read operations.
callback - The callback function using the signature function (err, response, payload) where:
err - Any error that may have occurred during handling of the request.
response - The HTTP Incoming Message object, which is also a readable stream.
payload - The payload in the form of a Buffer or (optionally) parsed JavaScript object (JSON).
So, the use of the get method is pretty straightforward (using your own example):
var callback = function(err, response, payload){
console.log(payload.toString()); // converting the buffer to a string and logging
};
Wreck.get(url, callback);

Categories

Resources