add events and make sending packets easier

This commit is contained in:
hippoz 2021-02-03 19:55:41 +02:00
parent 3c8434fb8a
commit 04e577acc8
Signed by: hippoz
GPG key ID: 7C52899193467641
4 changed files with 41 additions and 8 deletions

View file

@ -8,7 +8,10 @@ const wormhole = new Wormhole({ urls: [ '/hello' ], httpServer });
wormhole.on('connect', ({ socket, accept, reject }) => { wormhole.on('connect', ({ socket, accept, reject }) => {
accept(); accept();
socket.sendText('hello'); const buf = Buffer.from([0x41, 0x41, 0x41, 0x41]);
console.log(buf);
socket.send(buf);
socket.on('text', console.log);
}); });
httpServer.listen(8080); httpServer.listen(8080);

View file

@ -46,6 +46,8 @@ WebsocketFrame.prototype.toBuffer = function() {
this.MASK && packet.push(this.MaskingKey); this.MASK && packet.push(this.MaskingKey);
packet.push(this.PayloadData); packet.push(this.PayloadData);
console.log(packet);
return Buffer.concat(packet); return Buffer.concat(packet);
}; };

View file

@ -1,29 +1,49 @@
const EventEmitter = require('events');
const constants = require("./constants"); const constants = require("./constants");
const parser = require('./Parser'); const parser = require('./Parser');
class Socket { class Socket extends EventEmitter {
constructor({ initialState='CONNECTING', socket }) { constructor({ initialState='CONNECTING', socket }) {
super();
this._state = initialState; this._state = initialState;
this._socket = socket; this._socket = socket;
this._accepted = false; this._accepted = false;
this._fateDecided = false; // Wether the decision to accept or reject the socket was made this._fateDecided = false; // Wether the decision to accept or reject the socket was made
this._socket.on('data', (e) => { this._socket.on('data', (e) => {
if (this._state !== constants.states.OPEN) return; if (!this._isConnected()) return;
this._decodePayload(e.buffer); const packet = this._decodePayload(e.buffer);
if (packet.Opcode === constants.opcodes.TEXT_FRAME) {
this.emit('text', packet);
} else if (packet.Opcode === constants.opcodes.BINARY_FRAME) {
this.emit('binary', packet);
}
}); });
} }
} }
Socket.prototype.sendText = function(text) { Socket.prototype.send = function(payload) {
if (typeof payload === 'string') {
this._sendBuffer(Buffer.from(payload));
} else if (payload instanceof Buffer) {
this._sendBuffer(payload);
} else {
throw new Error(`Unsupported type ${typeof payload}, supported types are: string, Buffer`);
}
};
Socket.prototype._sendBuffer = function(buffer) {
const frame = new parser.WebsocketFrame(); const frame = new parser.WebsocketFrame();
frame.FIN = 1; frame.FIN = 1;
frame.RSVx = 0; frame.RSVx = 0;
frame.Opcode = 0x01; frame.Opcode = 0x01;
frame.MASK = 0; frame.MASK = 0;
const length = text.length; const length = buffer.byteLength;
console.log(length);
if (length > 125) { if (length > 125) {
frame.PayloadLen = 126; frame.PayloadLen = 126;
} else if (length >= 65536) { } else if (length >= 65536) {
@ -32,13 +52,13 @@ Socket.prototype.sendText = function(text) {
frame.PayloadLen = length; frame.PayloadLen = length;
} }
frame.PayloadLenEx = length; frame.PayloadLenEx = length;
frame.PayloadData = Buffer.from(text); frame.PayloadData = buffer;
this._socket.write(frame.toBuffer()); this._socket.write(frame.toBuffer());
}; };
Socket.prototype._decodePayload = function(payload) { Socket.prototype._decodePayload = function(payload) {
console.log(parser.parseWebsocketFrame(new DataView(payload))); return parser.parseWebsocketFrame(new DataView(payload));
}; };
Socket.prototype._setConnectionState = function(state) { Socket.prototype._setConnectionState = function(state) {
@ -52,4 +72,8 @@ Socket.prototype._setAccepted = function(state) {
this._accepted = state; this._accepted = state;
}; };
Socket.prototype._isConnected = function() {
return (this._fateDecided && this._isConnected && this._accepted === true);
}
module.exports = Socket; module.exports = Socket;

View file

@ -7,5 +7,9 @@ module.exports = {
OPEN: 'OPEN', OPEN: 'OPEN',
CLOSING: 'CLOSING', CLOSING: 'CLOSING',
CLOSED: 'CLOSED' CLOSED: 'CLOSED'
},
opcodes: {
'TEXT_FRAME': 0x01,
'BINARY_FRAME': 0x02
} }
} }