DEV Community

Ryo Ota
Ryo Ota

Posted on

Try QUIC in Node.js on Docker

Hi! I made a Docker image for QUIC in Node.js for everyone to try QUIC easily.

GitHub repository

Here is the GitHub repository.

GitHub logo nwtgck / docker-node-quic

Docker image for Node.js with QUIC

docker-node-quic

Docker image for Node.js with QUIC

Usage

You can docker-run with docker run -it nwtgck/node-quic as follows.

$ docker run -it nwtgck/node-quic
Welcome to Node.js v14.0.0-pre.
Type ".help" for more information.
> const { createQuicSocket } = require('net');
undefined

You can get more detail examples and descriptions about the usage of QUIC in Node.js in the following.
quic/quic.md at cee2e5d079ca2b55e421d81df1ad131c1bfeecc6 Β· nodejs/quic

Article

Here is an article to get example.

Try QUIC in Node.js on Docker - DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»




You can use the docker image by docker run -it nwtgck/node-quic and use QUIC by const { createQuicSocket } = require('net');.

Create echo server

As an example, let's create an echo server.

First, you can create self-signed certificates as follows.

mkdir ssl_certs
cd ssl_certs
openssl genrsa 2024 > server.key
openssl req -new -key server.key -subj "/C=JP" > server.csr
openssl x509 -req -days 3650 -signkey server.key < server.csr > server.crt
cd -

Second, create my_echo_server.js as follows.

// my_echo_server.js

const { createQuicSocket } = require('net');
const fs = require('fs');

const key  = fs.readFileSync('./ssl_certs/server.key');
const cert = fs.readFileSync('./ssl_certs/server.crt');
const ca   = fs.readFileSync('./ssl_certs/server.csr');
const port = 1234;

// Create the QUIC UDP IPv4 socket bound to local IP port 1234
const server = createQuicSocket({ endpoint: { port } });

// Tell the socket to operate as a server using the given
// key and certificate to secure new connections, using
// the fictional 'hello' application protocol.
server.listen({ key, cert, alpn: 'hello' });

server.on('session', (session) => {
  // The peer opened a new stream!
  session.on('stream', (stream) => {
    // Echo server
    stream.pipe(stream);
  });
});

server.on('listening', () => {
  // The socket is listening for sessions!
  console.log(`listening on ${port}...`);
  console.log('input something!');
});

const socket = createQuicSocket({
  client: {
    key,
    cert,
    ca,
    requestCert: true,
    alpn: 'hello',
    servername: 'localhost'
  }
});

const req = socket.connect({
  address: 'localhost',
  port,
});

req.on('secure', () => {
  const stream = req.openStream();
  // stdin -> stream
  process.stdin.pipe(stream);
  stream.on('data', (chunk) => console.log('client(on-secure): ', chunk.toString()));
  stream.on('end', () => console.log('client(on-secure): end'));
  stream.on('close', () => {
    // Graceful shutdown
    socket.close();
  });
  stream.on('error', (err) => console.error(err));
});

Next, enter a docker container as follows.

docker run -it -v $PWD:/playground nwtgck/node-quic bash

And, type the following commands in the container.

# Move the playground
cd /playground/
# Run echo server
node my_echo_server.js

In the container, you can use existing packages because npm command is available. You can expose UDP port by -p 1234:1234/udp with docker run.

Demo

Here is a demo.
Alt Text

Your inputs on stdin are echoed by the server.

Learn more

Oldest comments (1)

Collapse
 
akay777 profile image
akay777

can you please help that why docker image is not running?