Try QUIC in Node.js on Docker
Tags: node, quic, docker, javascript
Published: 2020-03-30 11:56:31

---
title: Try QUIC in Node.js on Docker
published: true
description: Try QUIC in Node.js on Docker
tags: Node.js,QUIC,Docker,JavaScript
---

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 nwtgck/docker-node-quic %}

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.

```bash
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.

```js
// 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.

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

And, type the following commands in the container.

```bash
# 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](https://dev-to-uploads.s3.amazonaws.com/i/yvrugre2awzlelpyzqmx.gif)

Your inputs on stdin are echoed by the server.

## Learn more
- Official document: [quic/quic.md at cee2e5d079ca2b55e421d81df1ad131c1bfeecc6 · nodejs/quic](https://github.com/nodejs/quic/blob/cee2e5d079ca2b55e421d81df1ad131c1bfeecc6/doc/api/quic.md)
- Echo server ref: [A QUIC Update for Node.js](https://www.nearform.com/blog/a-quic-update-for-node-js/)
- My Japanese post: <https://scrapbox.io/nwtgck/Node.js%E3%81%AEQUIC%E3%82%92%E5%85%88%E5%8F%96%E3%82%8A%E3%81%97%E3%81%A6%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86>