Skip to content

Commit a174f4f

Browse files
authored
chore: Added NodeJS examples - Socket code without using library. (#2)
1 parent a509792 commit a174f4f

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed

examples.manifest.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
- name: ilp
2+
lang: javascript
3+
path: examples/basic.js
4+
header: |-
5+
NodeJS client library [repo](https://github.com/questdb/nodejs-questdb-client).
6+
- name: ilp-auth-tls
7+
lang: javascript
8+
path: examples/auth_and_tls.js
9+
header: |-
10+
NodeJS client library [repo](https://github.com/questdb/nodejs-questdb-client).
11+
auth:
12+
kid: testUser1
13+
d: 5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48
14+
x: fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU
15+
y: Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac
16+
addr:
17+
host: localhost
18+
port: 9009

examples/auth_tls.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
const { TLSSocket } = require("tls")
2+
const { Crypto } = require("node-webcrypto-ossl")
3+
4+
const client = new TLSSocket()
5+
const crypto = new Crypto()
6+
7+
const HOST = "localhost"
8+
const PORT = 9009
9+
10+
const JWK = {
11+
kid: "testUser1",
12+
kty: "EC",
13+
d: "5UjEMuA0Pj5pjK8a-fa24dyIf-Es5mYny3oE_Wmus48",
14+
crv: "P-256",
15+
x: "fLKYEaoEb9lrn3nkwLDA-M_xnuFOdSt9y0Z7_vWSHLU",
16+
y: "Dt5tbS1dEDMSYfym3fgMv0B99szno-dFc1rYF9t0aac",
17+
}
18+
19+
async function write(data) {
20+
return new Promise((resolve) => {
21+
client.write(data, () => {
22+
resolve()
23+
})
24+
})
25+
}
26+
27+
async function authenticate(challenge) {
28+
// Check for trailing \\n which ends the challenge
29+
if (challenge.slice(-1).readInt8() === 10) {
30+
const apiKey = await crypto.subtle.importKey(
31+
"jwk",
32+
JWK,
33+
{ name: "ECDSA", namedCurve: "P-256" },
34+
true,
35+
["sign"],
36+
)
37+
38+
const signature = await crypto.subtle.sign(
39+
{ name: "ECDSA", hash: "SHA-256" },
40+
apiKey,
41+
challenge.slice(0, challenge.length - 1),
42+
)
43+
44+
await write(`${Buffer.from(signature).toString("base64")}\n`)
45+
46+
return true
47+
}
48+
49+
return false
50+
}
51+
52+
async function sendData() {
53+
const now = Date.now()
54+
await write(`test,location=us temperature=22.4 ${now * 1e6}`)
55+
await write(`test,location=us temperature=21.4 ${now * 1e6}`)
56+
}
57+
58+
async function run() {
59+
let authenticated = false
60+
let data
61+
62+
client.on("data", async function (raw) {
63+
data = !data ? raw : Buffer.concat([data, raw])
64+
65+
if (!authenticated) {
66+
authenticated = await authenticate(data)
67+
await sendData()
68+
setTimeout(() => {
69+
client.destroy()
70+
}, 0)
71+
}
72+
})
73+
74+
client.on("ready", async function () {
75+
await write(JWK.kid)
76+
})
77+
78+
client.connect(PORT, HOST)
79+
}
80+
81+
run()

examples/basic.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Raw socket connection with no validation and string quoting logic.
2+
// Refer to protocol description:
3+
// http://questdb.io/docs/reference/api/ilp/overview
4+
5+
"use strict"
6+
7+
const net = require("net")
8+
9+
const client = new net.Socket()
10+
11+
const HOST = "localhost"
12+
const PORT = 9009
13+
14+
function run() {
15+
client.connect(PORT, HOST, () => {
16+
const rows = [
17+
`trades,name=test_ilp1 value=12.4 ${Date.now() * 1e6}`,
18+
`trades,name=test_ilp2 value=11.4 ${Date.now() * 1e6}`,
19+
]
20+
21+
function write(idx) {
22+
if (idx === rows.length) {
23+
client.destroy()
24+
return
25+
}
26+
27+
client.write(rows[idx] + "\n", (err) => {
28+
if (err) {
29+
console.error(err)
30+
process.exit(1)
31+
}
32+
write(++idx)
33+
})
34+
}
35+
36+
write(0)
37+
})
38+
39+
client.on("error", (err) => {
40+
console.error(err)
41+
process.exit(1)
42+
})
43+
44+
client.on("close", () => {
45+
console.log("Connection closed")
46+
})
47+
}
48+
49+
run()

0 commit comments

Comments
 (0)