gRPC with synchronous calls in node application - node.js

I have an application which implements multiple gRPC servers.
The client side is implemented in nodeJS.
The client invokes multiple gRPC calls one after another.
Since in nodeJS, channel is created per ServiceClient , how to ensure that the first gRPC call is complete before the second gRPC call is invoked.
Is there a way to specify multiple ServiceClient to use same channel for all the communication ?
Is there a way to use synchronous gRPC calls in nodeJS ?

Node gRPC does not have synchronous calls. As with any asynchronous Node operation, you can ensure that two calls are made sequentially by invoking the second one in the completion callback of the first.
And no, there is not currently an API to have multiple client objects use the same channel.

I noticed this question is quite old, answered just in case someone still needs it in the future.
YES, call the second gRPC after the end event. Below is the client example.
const target = "localhost:50055";
const client = new proto.APINAME(target, grpc.credentials.createInsecure());
const call = client.APIMETHOD(metadata);
call.on("data", function(data) {
console.log(data);
});
call.on("end", function() {
// call the second gRPC
});

Related

In Meteor, is Meteor.wrapAsync blocking other calls?

In Meteor JS code, I am using HTTP.get method to call server inside a method. I must return result to client, so I am wrapping this function with
Meteor.wrapAsync to get a Synchronous function.
var httpSync = Meteor.wrapAsync(HTTP.get, this);
var result = httpSync(myUrl);
My question is - Will Meteor.wrapAsync(AsyncFunction) block other requests? Will it affect parallel execution of multiple requests?
It won't block the entire server. Meteor uses the fibers package to provide "synchronous looking" functions which don't block the entire server.
However, it will block other methods from the same user. If you want other methods from that user to run simultaneously, call this.unblock() inside the method:
On the server, methods from a given client run one at a time. The N+1th invocation from a client won't start until the Nth invocation returns. However, you can change this by calling this.unblock. This will allow the N+1th invocation to start running in a new fiber.
By the way, you don't need to Meteor.wrapAsync HTTP.get, since it can already be used synchronously. wrapAsync is intended to be used with external libraries that are not designed for Meteor.

NodeJS ZeroMQ , no callback for send?

I have multiple nodejs servers located at different locations and i need to create a IPC over tcp sockets and i am using ZeroMQ for that . I need something like request/response or pub/sub in a async way with affirmation that message is sent , but seeing the node-zeromq modules i found all the send methods are synchronous and there is no way to confirm the message the sent through a callback
In short ,
I need something like socket.send(message,function(err,res){;});
but i found this socket.send(message)
Anyone knows how to do this using ZeroMQ or any other way i could IPC reliablly and with a affirmation as response ?
UPDATE : Ive found https://github.com/visionmedia/axon , Axon and its req/rep send method has a callback , would be great if anyone can shed more light about this .Suggestions ?
You could use the request/reply pattern instead of the pub/sub pattern with ZMQ. I believe when you make a request, there is a callback to listen for the response, as opposed to pub.send()...
zeromq.node does yet not support reply callbacks for the send message.
There is an issue discussed for several years now on GitHub where people argue that it would be a sensible modification.
I followed the suggestion on another question since I would really like to use Promises in the higher levels and therefore need callbacks for the REQ/REP mechanism. I.e. the callback is invoked from the 'message' event handler:
var socket, onRepHandler, replyCallback, send;
socket = zmq.socket('req');
onRepHandler = function (reply) {
// HACK
// This handler is a workaround until zeromq.node supports
// direct callback for REQ/REP:
// https://github.com/JustinTulloss/zeromq.node/issues/48
if (replyCallback) {
replyCallback(reply);
}
replyCallback = undefined;
};
socket.on('message', onRepHandler(msg));
socket.connect(address);
// Send method with callback
send = function (msg, repcb) {
if (replyCallback) {
throw new Error('Cannot send request before receiving reply of preceding request!');
}
replyCallback = repcb;
socket.send(msg);
}
It feels like a questionable hack but I hope the zeromq.node library gets updated eventually.

Architecting a node.js application around socket.io

I'm writing an application in Node.js/Express based around websockets. I'm using Node's EventEmitter in conjunction with socket.io for a nearly completely event-driven app.
I wonder if this this is a good architecture though. My main socket is managed in app.js right now, and has code like this:
socket.on(Events.InitialFetch, function(battle_id){
dispatcher.emit(Events.InitialFetch, battle_id);
});
dispatcher.on(Events.InitialFetched, function(data){
socket.emit(Events.InitialFetched, data);
});
... while in my controller, I have code like this:
dispatcher.on('initial-fetch', function(data){
Battle.findOne({_id: data})
.populate('players')
.populate('owner')
.exec(function(err, battle){
if (err) {
}
else {
dispatcher.emit(Events.InitialFetched, battle);
}
});
});
Instead of the normal RESTful routing. My concern is that it's a little confusing (ie 'fetch' and 'fetched' for describing data flow) and the fact that I'm basically passing methods from one type of event emitter (socket.io) to another (Event.EventEmitter).
How can this be architected better? Would it be better to have the controllers directly access the socket instead of using EventEmitter as a bus? How can I make the names of my events more clear?
I wouldn't worry about using multiple event emitters. They are kind good primitive to build upon in Node.js. As for design, I find a good question to ask is how deeply I have coupled my components.
By using an non-socket.io event emitter for your controller, Socket.io is an independent transport from the controller. This is good.
As a final stage, you should wire the two together using dependency injection. In your server.js file create your dispatcher, then initialize your socket.io module passing the dispatcher as a dependency.
var dispatcher = require('./dispatcher')
var socket_transport = require('./socket_transport')
socket_transport.init_with_dispatcher(dispatcher);
This will let you test your dispatcher independently of the transport. Debugging socket.io can be difficult.

Communicating between two different processes in Node.js

The issue is:
Lets assume we have two Node.js processes running: example1.js and example2.js.
In example1.js there is function func1(input) which returns result1 as a result.
Is there a way from within example2.js to call func1(input) and obtain result1 as the outcome?
From what I've learned about Node.js, I have only found one solution which uses sockets for communication. This is less than ideal however because it would require one process listening on a port. If possible I wish to avoid that.
EDIT: After some questions I'd love to add that in hierarchy example1.js cannot be child process of example2.js, but rather the opposite. Also if it helps -- there can be only one example1.js processing its own data and many example2.js's processing own data + data from first process.
The use case you describe makes me think of dnode, with which you can easily expose functions to be called by different processes, coordinated by dnode, which uses network sockets (and socket.io, so you can use the same mechanism in the browser).
Another approach would be to use a message queue, there are many good bindings for different message queues.
The simplest way to my knowledge, is to use child_process.fork():
This is a special case of the spawn() functionality for spawning Node processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. The channel is written to with child.send(message, [sendHandle]) and messages are received by a 'message' event on the child.
So, for your example, you could have example2.js:
var fork = require('child_process').fork;
var example1 = fork(__dirname + '/example1.js');
example1.on('message', function(response) {
console.log(response);
});
example1.send({func: 'input'});
And example1.js:
function func(input) {
process.send('Hello ' + input);
}
process.on('message', function(m) {
func(m);
});
May be you should try Messenger.js. It can do IPC in a handy way.
You don't have to do the communication between the two processes by yourself.
Use Redis as a message bus/broker.
https://redis.io/topics/pubsub
You can also use socket messaging like ZeroMQ, which are point to point / peer to peer, instead of using a message broker like Redis.
How does this work?
With Redis, in both your node applications you have two Redis clients doing pub/sub. So each node.js app would have a publisher and subscriber client (yes you need 2 clients per node process for Redis pub/sub)
With ZeroMQ, you can send messages via IPC channels, directly between node.js processes, (no broker involved - except perhaps the OS itself..).

Is there a browserless websocket client for Node.js that does not need to use a browser?

Socket.IO, etc all require the using of browser on the client side....just wondering, how can we have browserless websocket client for node.js ?
Current Recommendation
Use WebSocket-Node with my wrapper code (see below). As of this writing, no other public project that i know of supports the new hybi specification, so if you want to emulate current browser releases, you'll need WebSocket-Node. If you want to emulate older browsers, such as mobile Safari on iOS 4.2, you'll also need one of the other libraries listed below, but you'll have to manage "WebSocket" object name collisions yourself.
A list of public WebSocket client implementations for node.js follows.
Socket.IO
The socket.io client-test WebSocket implementation does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/LearnBoost/socket.io/blob/master/support/node-websocket-client/lib/websocket.js
i'm asking if they intend to update to hybi 7+:
http://groups.google.com/group/socket_io/browse_thread/thread/d27320502109d0be
Node-Websocket-Client
Peter Griess's "node-websocket-client" does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/pgriess/node-websocket-client/blob/master/lib/websocket.js
WebSocket-Node
Brian McKelvey's WebSocket-Node has a client implementation for hybi 7-17 (protocol version 7-13), but the implementation does not provide a browser-style WebSocket object.
https://github.com/Worlize/WebSocket-Node
Here is the wrapper code I use to emulate the browser-style WebSocket object:
/**
* Wrapper for Worlize WebSocketNode to emulate the browser WebSocket object.
*/
var WebSocketClient = require('./WorlizeWebSocketNode/lib/websocket').client;
exports.WebSocket = function (uri) {
var self = this;
this.connection = null;
this.socket = new WebSocketClient();
this.socket.on('connect', function (connection) {
self.connection = connection;
connection.on('error', function (error) {
self.onerror();
});
connection.on('close', function () {
self.onclose();
});
connection.on('message', function (message) {
if (message.type === 'utf8') {
self.onmessage({data:message.utf8Data});
}
});
self.onopen();
});
this.socket.connect(uri);
}
exports.WebSocket.prototype.send = function (data) {
this.connection.sendUTF(data);
}
SockJS
Just for reference, Marek Majkowski's SockJS does not include a node client. SockJS's client library is simply a browser dom wrapper.
https://github.com/sockjs/sockjs-client
Having just gone through this, I have to recommend:
https://github.com/Worlize/WebSocket-Node
Due to it's excellent documentation.
https://github.com/einaros/ws comes a close second.
Both are active and being kept up to date at this time.
Remy Sharp (#rem) wrote a Socket.io-client implementation that works on the server. I think this is what you're looking for: https://github.com/remy/Socket.io-node-client
A Node.js server is in no way bound to a web browser as a client. Any program can use whatever socket library is provided by its supporting libraries to make a call to a Node.js server.
EDIT
Responding to your comment: don't forget that Node.js is Javascript! If you want to execute code periodically -- in much the same way that a daemon process might -- you can use setInterval to run a callback every n milliseconds. You should be able to do it right there in your node program.
Right now (in Oct 2012) the recommended way to do it is using a the socket.io-client library, which is available at https://github.com/LearnBoost/socket.io-client

Resources