Skip to content

Instantly share code, notes, and snippets.

@yosuke-furukawa
Last active July 5, 2024 02:16
Show Gist options
  • Save yosuke-furukawa/b053016237ab524ef1f521f2db40919e to your computer and use it in GitHub Desktop.
Save yosuke-furukawa/b053016237ab524ef1f521f2db40919e to your computer and use it in GitHub Desktop.
Node.js QUIC example: echo server
// caution: required node.js v15 built with `--experimetantal-quic` option.
// node quic.js
const { createQuicSocket } = require('net');
const { readFileSync } = require('fs');
/*
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
*/
const key = readFileSync('./server.key');
const cert = readFileSync('./server.crt');
const ca = readFileSync('./server.csr');
const requestCert = true;
const alpn = 'echo';
const port = 5678;
const server = createQuicSocket({
// Bind to local UDP port 5678
endpoint: { port },
});
server.listen({
key,
cert,
alpn,
});
server.on('listening', () => {
console.log(`QUIC server is listening on ${port}`);
});
server.on('session', async (session) => {
session.on('stream', (stream) => {
// Echo server!
stream.pipe(stream);
});
const stream = await session.openStream();
stream.end('hello from the server');
});
const socket = createQuicSocket({
client: {
key,
cert,
ca,
requestCert: true,
alpn: 'echo',
servername: 'localhost'
}
});
(async function() {
const req = await socket.connect({
address: 'localhost',
port,
});
req.on('secure', async () => {
const stream = await req.openStream();
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));
});
})();
@yosuke-furukawa
Copy link
Author

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

  req.on('secure', async () => {
    const stream = await req.openStream();
    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));
  });
})();

This is the client code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment