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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| class CustomWebsocket extends CustomReadSocket { timer = null constructor(req, socket, head, options) { super(req, socket, head) this.options = options
this.timeout() this.socket.on('data', () => { this.timeout() }) }
send(message) { const buffer = Buffer.from(message) const list = this.buildDataFrameList('text', buffer) list.forEach((frame) => { this.socket.write(frame) }) this.timeout() }
ping() { const frame = this.buildFrame('ping') this.socket.write(frame) this.timeout() }
pong() { const frame = this.buildFrame('pong') this.socket.write(frame) this.timeout() }
close() { const frame = this.buildFrame('close') this.socket.write(frame) this.socket.end() process.nextTick(() => { this.socket.destroy() }) }
timeout() { const { timeout = 10000 } = this.options || {} clearTimeout(this.timer) this.timer = setTimeout(() => { this.ping() }, timeout) }
buildDataFrameList(type, buffer) { const bufferList = [] let tempBuffer = buffer while (tempBuffer.length) { bufferList.push(tempBuffer.slice(0, this.MAX_FRAME_SIZE)) tempBuffer = tempBuffer.slice(this.MAX_FRAME_SIZE) } const len = bufferList.length return bufferList.map((buf, index) => this.buildFrame(index ? 'continue' : type, len === index + 1, buf), ) }
buildFrame(dataType, isLast = true, buffer = null) { let firstByte = isLast ? 0x80 : 0x00 switch (`${dataType || ''}`.toLowerCase()) { case 'continue': { firstByte = firstByte | 0x00 break } case 'text': { firstByte = firstByte | 0x01 break } case 'binary': { firstByte = firstByte | 0x02 break } case 'close': { firstByte = firstByte | 0x08 break } case 'ping': { firstByte = firstByte | 0x09 break } case 'pong': { firstByte = firstByte | 0x0a break } default: { console.log('others') } } let secondByte = 0x00
if (buffer && buffer.length) { const lenByteList = [] const len = buffer.length if (len <= 125) { secondByte = secondByte | len } else if (len >= 126 && len < 65536) { secondByte = secondByte | 0x7e for (let i = 0; i < 2; i++) { lenByteList.push(0xff & (len >> (i * 8))) } } else { secondByte = secondByte | 0x7f for (let i = 0; i < 8; i++) { lenByteList.push(0xff & (len >> (i * 8))) } } lenByteList.reverse() const prefixBuffer = Buffer.from([firstByte, secondByte, ...lenByteList]) return Buffer.concat([prefixBuffer, buffer]) } return Buffer.from([firstByte, secondByte]) } }
|