Skip to content

Commit 4248678

Browse files
committed
Add http2 on the same port with websocket
1 parent 39710d7 commit 4248678

File tree

7 files changed

+186
-0
lines changed

7 files changed

+186
-0
lines changed

http2-ws/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Start HTTP server
2+
3+
## With self-signed certificate (for testing)
4+
5+
- Generate certificates, run: `./cert/generate.sh`
6+
- Start server: `node server.js`
7+
- Open in browser: `https://127.0.0.1:8000/`
8+
9+
## With certbot (for production)
10+
11+
- Let's Encrypt is a free certificate authority: https://letsencrypt.org/
12+
- Use Certbot (free tool for automatically generatinging Let’s Encrypt
13+
certificates to enable HTTPS): https://certbot.eff.org/
14+
- Install: `dnf -y install certbot`
15+
- Generate certificate:
16+
`certbot certonly --standalone -d www.domain.com -d domain.com -m your.name@domain.com --agree-tos --no-eff-email`
17+
- Copy certificate:
18+
`cp /etc/letsencrypt/live/domain.com/fullchain.pem ./cert/cert.pem`
19+
- Copy private key:
20+
`cp /etc/letsencrypt/live/domain.com/privkey.pem ./cert/key.pem`
21+
- Or use your web server for challenge exchange:
22+
`certbot certonly --webroot -w ./ -d domain.com -m your.name@domain.com --agree-tos --no-eff-email`

http2-ws/cert/generate.ext

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
authorityKeyIdentifier=keyid,issuer
2+
basicConstraints=CA:FALSE
3+
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
4+
subjectAltName = @alt_names
5+
6+
[alt_names]
7+
DNS.1 = example.com
8+
IP.1 = 127.0.0.1
9+
IP.2 = ::1

http2-ws/cert/generate.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cd "$(dirname "$0")"
2+
openssl genrsa -out key.pem 3072
3+
openssl req -new -out self.pem -key key.pem -subj '/CN=localhost'
4+
openssl req -text -noout -in self.pem
5+
openssl x509 -req -days 1024 -in self.pem -signkey key.pem -out cert.pem -extfile generate.ext

http2-ws/index.html

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<body>
4+
<h1>Page example</h1>
5+
<div id="log"></div>
6+
<style>
7+
input { border: 1px solid green; }
8+
</style>
9+
<script>
10+
const log = document.getElementById('log');
11+
12+
const writeLine = (text) => {
13+
const line = document.createElement('div');
14+
line.innerHTML = `<p>${text}</p>`;
15+
log.appendChild(line);
16+
};
17+
18+
const socket = new WebSocket('wss://127.0.0.1:8000');
19+
20+
socket.addEventListener('open', () => {
21+
socket.send('Hello!');
22+
writeLine('connected');
23+
});
24+
25+
socket.addEventListener('close', () => {
26+
writeLine('closed');
27+
});
28+
29+
socket.addEventListener('message', ({ data }) => {
30+
writeLine(data);
31+
});
32+
</script>
33+
</body>
34+
</html>

http2-ws/package-lock.json

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

http2-ws/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "http2WebsocketExample",
3+
"version": "1.0.0",
4+
"author": "Timur Shemsedinov <timur.shemsedinov@gmail.com>",
5+
"description": "HTTP2 and Websocket Example",
6+
"license": "MIT",
7+
"dependencies": {
8+
"ws": "^8.13.0"
9+
}
10+
}

http2-ws/server.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
3+
const fs = require('node:fs');
4+
const http2 = require('node:http2');
5+
const WebSocket = require('ws');
6+
7+
const index = fs.readFileSync('./index.html', 'utf8');
8+
const user = { name: 'jura', age: 22 };
9+
10+
const routing = {
11+
'/': index,
12+
'/user': user,
13+
'/user/name': () => user.name.toUpperCase(),
14+
'/user/age': () => user.age,
15+
'/hello': { hello: 'world', andArray: [1, 2, 3, 4, 5, 6, 7] },
16+
'/api/method1': (req, res) => {
17+
console.log(req.url + ' ' + res.statusCode);
18+
return { status: res.statusCode };
19+
},
20+
'/api/method2': (req) => ({
21+
user,
22+
url: req.url,
23+
cookie: req.headers.cookie
24+
}),
25+
};
26+
27+
const types = {
28+
object: JSON.stringify,
29+
string: (s) => s,
30+
undefined: () => 'not found',
31+
function: (fn, req, res) => JSON.stringify(fn(req, res)),
32+
};
33+
34+
const key = fs.readFileSync('./cert/key.pem');
35+
const cert = fs.readFileSync('./cert/cert.pem');
36+
const options = { key, cert };
37+
38+
const server = http2.createSecureServer(options, (req, res) => {
39+
const data = routing[req.url];
40+
const type = typeof data;
41+
const serializer = types[type];
42+
const result = serializer(data, req, res);
43+
res.end(result);
44+
});
45+
46+
server.listen(8000);
47+
console.log('Open: https://127.0.0.1:8000');
48+
49+
const ws = new WebSocket.Server({ server });
50+
51+
ws.on('connection', (connection, req) => {
52+
const ip = req.socket.remoteAddress;
53+
console.log(`Connected ${ip}`);
54+
connection.on('message', (message) => {
55+
console.log('Received: ' + message);
56+
});
57+
connection.on('close', () => {
58+
console.log(`Disconnected ${ip}`);
59+
});
60+
});
61+
62+
setInterval(() => user.age++, 2000);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy