-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathws.ts
83 lines (71 loc) · 2.75 KB
/
ws.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import https from "node:https";
import http from "node:http";
import crypto from "node:crypto";
import { Socket } from "node:net"
import event from "node:events";
export class WebSocket extends event.EventEmitter {
hostname:string
protocol:string
pathname:string
request:{
(options: string | https.RequestOptions | URL, callback?: ((res: http.IncomingMessage) => void) | undefined): http.ClientRequest;
(url: string | URL, options: https.RequestOptions, callback?: ((res: http.IncomingMessage) => void) | undefined): http.ClientRequest;
}
port:number
req:http.ClientRequest
socket:null|Socket
constructor(url:string) {
super()
const { hostname, protocol, pathname, port } = new URL(url)
const CheckWSS = protocol === "wss:"
this.hostname = hostname
this.protocol = protocol
this.pathname = pathname
this.request = CheckWSS ? https.request : http.request
this.port = port === "" ? CheckWSS ? 443 : 80 : Number(port)
this.socket = null
const key = crypto.randomBytes(16).toString('base64')
this.req = this.request({
port:this.port,
hostname:this.hostname.startsWith("[") ? this.hostname.slice(1,-1) : this.hostname,
path:pathname,
method:`GET`,
headers: {
"Host": `${this.hostname}:${this.port}`,
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": key,
"Sec-WebSocket-Version": "13"
}
})
this.req.on("upgrade",(res,socket,head) => {
this.socket = socket
socket.on("connect",() => this.emit("open"))
socket.on("data",(data) => {
let buf = Buffer.from(data).slice(2)
this.emit("message",buf)
})
socket.on("close",() => this.emit("close"))
})
this.req.end()
}
send(content:any) {
if (this.socket === null) throw new Error("Cannot Connect WebSocket")
let buf = Buffer.from(content, "utf-8")
let newBuffer = Buffer.alloc(buf.length + 6)
buf.copy(newBuffer, 6)
newBuffer[0] = 0x81
newBuffer[1] = 0x80 | buf.length
const mask = Buffer.from([
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256)
])
mask.copy(newBuffer, 2)
for (let i = 0; i < buf.length; i++) {
newBuffer[i + 6] ^= mask[i % 4]
}
this.socket.write(newBuffer);
}
}