HTTP/2 – offer/answer signaling for WebRTC call

HTTP ( Hyper Text Transfer Protocol ) is the top application layer protocol atop the Tarnsport layer ( TCP ) and the Network layer ( IP )

HTTP/1.1

release in 1997. Since HTTP/1 allowed only 1 req at a time , HTTP/1.1

Allows one one outstanding connection on a TCP session but allowed request pieplinig to achieve concurency.

HTTP/2

In 2015, HTTP/2 was released which aimed at reducing latency while delivering heavy graphics, videos and other media cpmponents on web page especially on mobile sites .
optimizes server push and service workers

FRAMES

A key differenet between Http/1.1 and HTTP/2 is the fact that former transmites requests and reponses in plaintext whereas the later encapsulates them into binary format , proving more features and scope for optimzation.

Thus at protocol level , it is all about frames of bytes which are part of stream.

“enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection. It also introduces unsolicited push of representations from servers to clients.”

Hypertext Transfer Protocol Version 2 (HTTP/2) draft-ietf-httpbis-http2-latest
https://http2.github.io/http2-spec/

It is important to know that Browsers only implement HTTP/2 under HTTPS, thus TLS connection is must for whichw e need certs ad keys signed by CA ( either self signed using openssl , signed by public CA like godaddy , verisign or letsencrypt)

Compatibility Layer between HTTP1.1 and HTTP2.0 in node

Nodejs >9 provides http2 as native module. Exmaple of using http2 with compatibility layer

const http2 = require('http2');
const options = {
 key: 'ss/key', // path to key
 cert: 'ssl/cert' // path to cert
};

const server = http2.createSecureServer(options, (req, res) => {
    req.addListener('end', function () {
        file.serve(req, res);
    }).resume();
});
server.listen(8084);

in replacement for existing server http/https server

const https = require('https');
app = https.createServer(options, function (request, response) {
    request.addListener('end', function () {
        file.serve(request, response);
    }).resume();
});

app.listen(8084);

Socket.io/ Websocket over HTTP2

The WebSocket Protocol uses the HTTP/1.1 Upgrade mechanism to transition a TCP connection from HTTP into a WebSocket connection

Due to its multiplexing nature, HTTP/2 does not allow connection-wide header fields or status codes, such as the Upgrade and Connection request-header fields or the 101 (Switching Protocols) response code. These are all required for opening handshake.

Ideally the code shouldve looekd like this with backward compatiability layer , but continue reading update ..

var app = http2
    .createSecureServer(options, (req, res) => {
        req.addListener('end', function () {
            file.serve(req, res);
        }).resume();
    })
    .listen(properties.http2Port);

var io = require('socket.io').listen(app);
io.origins('*:*');
io.on('connection', onConnection); // evenet handler onconnection

Error during WebSocket handshake: Unexpected response code: 403

update May 2020 : I tried using the http2 server with websocket like mentioned above ,h owever many many hours of working around WSS over HTTP2 secure server , I consistencly kept faccing the ECONNRESET issues after couple of seconds , which would crash the server

client 403
server ECONNRESET

Therefore leaving the web server to server htmll conetnt I reverted the siganlling back to HTTPs/1.1 given the reasons for sticking with WSS is low latency and existing work that was already put in.

Example Repo : https://github.com/altanai/webrtcdevelopment/tree/htt2.0

Reading Further of exploring HTTP CONNECT methods for setting WS handshake . Will update this section in future if it works .

Streams

A “stream” is an independent, bidirectional sequence of frames exchanged between the client and server within an HTTP/2 connection.
A single HTTP/2 connection can contain multiple concurrently open streams, with either endpoint interleaving frames from multiple streams.

Core http2 module provides new core API (Http2Stream), accessed via a “stream” listener:

const http2 = require('http2');
const options = {
 key: 'ss/key', // path to key
 cert: 'ssl/cert' // path to cert
};

const server = http2.createSecureServer(options, (stream, headers) => {
    stream.respond({ ':status': 200 });
    stream.end('some text!');
});
server.listen(3000);

Other features

  • stream multiplexing
  • stream Prioritization
  • header compression
  • Flow Control
  • support for trailer

Persistent , one connection per origin.

With the new binary framing mechanism in place, HTTP/2 no longer needs multiple TCP connections to multiplex streams in parallel; each stream is split into many frames, which can be interleaved and prioritized. As a result, all HTTP/2 connections are persistent, and only one connection per origin is required,

Server Push

bundling multiple assets and resources into a single HTTP/2  and lets the srever proactively push resources to client’s cache .

Server issues PUSH_PROMISE , client validates whether it needs the resource of not. If the client matches it then they will load like regular GET call

The PUSH_PROMISE frame includes a header block that contains a complete set of request header fields that the server attributes to the request.

After sending the PUSH_PROMISE frame, the server can begin delivering the pushed response as a response on a server-initiated stream that uses the promised stream identifier.

Client receives a PUSH_PROMISE frame and can either chooses to accept the pushed response or if it does not wish to receive the pushed response from the server it can can send a RST_STREAM frame, using either the CANCEL or REFUSED_STREAM code and referencing the pushed stream’s identifier.

Push Stream Support

-tbd

respondWithFile() and respondWithFD() APIs can send raw file data that bypasses the Streams API.

Related technologies

MIME

Multipurpose Internet Mail Extensions (MIME) is an Internet standard that extends the format of email messages to support text in character sets other than ASCII, as well as attachments of audio, video, images, and application programs. Message bodies may consist of multiple parts, and header information may be specified in non-ASCII character sets.

Email messages + MIME : transmitted with standard protocols, such as the Simple Mail Transfer Protocol (SMTP), the Post Office Protocol (POP), and the Internet Message Access Protocol (IMAP).

MIME in HTTP in WWW : servers insert a MIME header field at the beginning of any Web transmission. Clients use the content type or media type header to select an appropriate viewer application for the type of data indicated. Browsers typically contain GIF and JPEG image viewers.

MIME header fields

MIME version

MIME-Version: 1.0

Content Type

Content-Type: text/plain

multipart/mixed , text/html, image/jpeg, audio/mp3, video/mp4, and application/msword

content disposition

Content-Disposition: attachment; filename=genome.jpeg;
  modification-date="Wed, 12 Feb 1997 16:29:51 -0500";

Content-Transfer-Encoding

References :

NodeJS

Simple words :

Nodejs lets you write web apps that use Javascript on both the server and the client, so you don’t need to know multiple programming languages to program your website. It’s also really good at handling real-time concurrent web applications, which makes it a great choice for a lot of modern web apps.

Technically :

Node.js is different from JavaScript development in a browser . Technically speaking it makes use of Google’s V8 VM, the same runtime environment for JavaScript that Google Chrome uses.

  • cross-platform runtime environment and a library for running applications written in JavaScript
  • uses non-blocking I/O and asynchronous events.

Nodejs just runs on one  CPU core processor in an asynchronous, single-threaded, event-driven execution model.It contains a built-in asynchronous I/O library for file, socket and HTTP communication.

HTTP and socket support allows Node.js to act as a web server without additional web server software such as Apache.

Node.js vs traditional server-side scripting environments (eg: PHP, Python, Ruby, etc).

Setup

The steps to setup the nodejs environment are as follows :

  1. Get a web browser . I am using chrome v35 on ubuntu and windows.
  2. Get the installation of nodejs from this site http://nodejs.org/download/

nodejs1

It is available in form of windows installer , macintosh installer , linux binaries and from source code . Lets us just use linux binaries .

  1. Note the location of nodejs installation there should be an executable file there name nodejs.nodejs
  2. To start nodejs , just goto terminal in this location and type “ node “.

To load a script type “ node <name of script>.js

…………………………………..CLI ( command Line Interface……………………..

nodejs (1)

…………………………………Functions……………………………………………….

Another simple example for function call for console output .Here we are trying to call a function from another function  . First example is to call print function through now function . The second example is the definition of print function inline inside parameter list of now function .

consoletest.js

function print(status) {
console.log(status);
}
 
function now(func2name, value) {
func2name(value);
}
 
now(say, “Running”);

output:

altanai@tcs:~/nodejsscripts$ node consoletest.js

Running

This code passes the function print as the first parameter to the now function. The print function is called inside now function .

Another way to achieve the above logic through function-inplace

consoletest2.js

function now(func2name, value) {
func2name(value);
}
 
now(function(status){ console.log(status) }, “Running”);

output:

altanai@tcs:~/nodejsscripts$ node consoletest2.js

Running

……………………………………… Different script Modules/Files ………………..

Make a js file server.js

var http = require(“http”);
function start() {
function onRequest(request, response) {
 console.log(“Request received for Http on server.js.”);
 response.writeHead(200, {“Content-Type”: “text/plain”});
 response.write(“Running onRequest logic from server.js”);
 response.end();
}
 
http.createServer(onRequest).listen(8888);
console.log(“Inside server.js”);
}
exports.start = start;

 

Make another js file which is the main file to be loaded onto nodejs. Main.js

var server = require(“./server”);
console.log(“Inside main.js”);
server.start();

start this file from node

console output

nodejs (2)

web output

nodejs (3)

………………………………………… HTTP Server …………………………………

Make a Javascript file for creating a HTTP server and displaying some text on webpage as well as console . Lets us name it helloworld.js. The code in that file is

var http = require(‘http’);
 
http.createServer(function (request, response) {
response.writeHead(200, {‘Content-Type’: ‘text/plain’});
response.end(‘Display text on webpage – Hello World\n’);  
/*check this address http://127.0.0.1:8124/ in browser */
}).listen(8124);
 
console.log(‘Display text on console – Server running ‘);

/* check terminal screen */

Run it on console using command “node helloworld.js”

nodejs (5)

Check output in browser

nodejs (4)

Explanation :

The code for creation of HTTP server is

var http = require(“http”);
var server = http.createServer();
server.listen(8888);