Skip to content

Instantly share code, notes, and snippets.

@rameshvarun
Last active August 29, 2019 18:59
Show Gist options
  • Save rameshvarun/707f2def2c121c21ab50 to your computer and use it in GitHub Desktop.
Save rameshvarun/707f2def2c121c21ab50 to your computer and use it in GitHub Desktop.
How the HTTP2 API could be used to implement a streaming RPC more easily than other transport layers.
var http2 = require('http2');
var net = require('net');
var logger = require('bunyan').createLogger({ name: 'Test Logger' });
// Creating the server
var socket = net.connect(8080, 'localhost', function(c) {
// Use the HTTP2 Framing layer on this conncetion.
var endpoint = new http2.protocol.Endpoint(logger, 'CLIENT', {});
endpoint.pipe(socket).pipe(endpoint);
// Start the first RPC - do another RPC 3 seconds later.
makeRPC('Stream 1');
setTimeout(function() {
makeRPC('Stream 2');
}, 3000);
function makeRPC(name) {
// Create a stream with the server - corresponding to a single RPC call.
var stream = endpoint.createStream();
// Send the service/method name, along with the initial arguments in the header.
console.log('Call FindInProjectService/search');
stream.headers({
':method' : 'FindInProjectService/search',
':arguments' : '[3, 4, "nuclide://file.txt", true]'
});
stream.on('data', function(data) {
console.log('Update from ' + name + ': ' + data);
});
// After 5 seconds, cancel search.
setTimeout(function() {
console.log('Cancelling search.');
stream.write('close');
}, 5000);
}
});

HTTP2 Streaming RPC

Output

Server

RPC from client to FindInProjectService/search
Sending search update.
Sending search update.
RPC from client to FindInProjectService/search
Sending search update.
Sending search update.
Sending search update.
Cancelling search.
Sending search update.
Sending search update.
Sending search update.
Cancelling search.

Client

Call FindInProjectService/search
Update from Stream 1: Found new match.
Update from Stream 1: Found new match.
Call FindInProjectService/search
Update from Stream 1: Found new match.
Update from Stream 2: Found new match.
Update from Stream 1: Found new match.
Cancelling search.
Update from Stream 2: Found new match.
Update from Stream 2: Found new match.
Update from Stream 2: Found new match.
Cancelling search.
{
"dependencies": {
"bunyan": "^1.4.0",
"http2": "^3.2.0"
}
}
var http2 = require('http2');
var net = require('net');
var logger = require('bunyan').createLogger({ name: 'Test Logger' });
// Creating the server
var server = net.createServer(function(c) {
var endpoint = new http2.protocol.Endpoint(logger, 'SERVER', {});
endpoint.pipe(c).pipe(endpoint);
// A client has requested a bidirectional stream - this will correspond to
// a single RPC call, and its associated data.
endpoint.on('stream', function(stream) {
var interval = null;
stream.on('headers', function(headers) {
console.log("RPC from client to " + headers[':method']);
interval = setInterval(function() {
console.log('Sending search update.');
stream.write('Found new match.');
}, 1000);
});
stream.on('data', function() {
console.log('Cancelling search.');
clearInterval(interval);
stream.end();
});
});
});
server.listen(8080);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment