Conversation
lib/server.js
Outdated
|
|
||
| if (balancer) return; | ||
| this.wsServer = new ws.Server({ server: this.httpServer }); | ||
| this.wsServer = new WebsocketServer(this.httpServer); |
There was a problem hiding this comment.
I'd propose to be compatible with ws:
| this.wsServer = new WebsocketServer(this.httpServer); | |
| this.wsServer = new WebsocketServer({ server: this.httpServer }); |
| GOING_AWAY: { | ||
| reason: 'Going away', | ||
| buf: Buffer.from([ | ||
| 0x88, 0xc, 0x3, 0xe9, 0x47, 0x6f, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x77, | ||
| 0x61, 0x79, | ||
| ]), | ||
| }, |
There was a problem hiding this comment.
Let's hold strings as ascii strings and all unprintable as hex, for example:
| GOING_AWAY: { | |
| reason: 'Going away', | |
| buf: Buffer.from([ | |
| 0x88, 0xc, 0x3, 0xe9, 0x47, 0x6f, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x77, | |
| 0x61, 0x79, | |
| ]), | |
| }, | |
| GOING_AWAY: { | |
| reason: 'Going away', | |
| buf: Buffer.concat([ | |
| Buffer.from([0x88, 0x0c, 0x03, 0xe9]), | |
| Buffer.from('Going away', 'utf8'), | |
| ]), | |
| }, |
lib/websocket/frame.js
Outdated
| CLOSE_CODES, | ||
| TWO_32, | ||
| } = require('./constants'); | ||
| const { Result } = require('./utils/result'); |
There was a problem hiding this comment.
Always add extensions in require
| const { Result } = require('./utils/result'); | |
| const { Result } = require('./utils/result.js'); |
lib/websocket/frame.js
Outdated
| module.exports = { | ||
| Frame, | ||
| }; |
There was a problem hiding this comment.
| module.exports = { | |
| Frame, | |
| }; | |
| module.exports = { Frame }; |
| on(event, cb) { | ||
| if (event === 'open') this._openCb = cb; | ||
| else if (event === 'message') this._messageCb = (buf) => cb(buf); | ||
| else if (event === 'frame') this._frameCb = cb; | ||
| else if (event === 'ping') this._pingCb = (buf) => cb(buf); | ||
| else if (event === 'pong') this._pongCb = (buf) => cb(buf); | ||
| else if (event === 'close') this._closeCb = cb; | ||
| } |
There was a problem hiding this comment.
We can just use EventEmitter
There was a problem hiding this comment.
Yes, that’s a good idea — much cleaner than mocking everything. Done
| // Methods: send(data), sendFrame(opcode, payload, { fin=true, mask=true }), | ||
| // sendText, sendBinary, ping, close | ||
| class ProtocolClient { | ||
| constructor(url) { |
There was a problem hiding this comment.
Wery long constructor, maybe we can decompose, for example, extracting collection:
{ [opcode]: [handler] }
| @@ -0,0 +1,35 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
Should be moved to metautil
There was a problem hiding this comment.
Should I move the Result class to metautil, or do you think it would be better to introduce an algebraic data types?
There was a problem hiding this comment.
Yes, please find an issue there or just create new in metautil and PR
c577f9d to
67deceb
Compare
| @@ -0,0 +1,35 @@ | |||
| 'use strict'; | |||
There was a problem hiding this comment.
Yes, please find an issue there or just create new in metautil and PR
| this.emit( | ||
| 'error', | ||
| new Error('Protocol error: Unexpected CONTINUATION without start'), | ||
| ); | ||
| return void this.#close( | ||
| Frame.protocolErrorClose( | ||
| PROTOCOL_ERROR_SUBTYPES.COMMON, | ||
| this.#isClient, | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Use intermediate variables here and in other places
| this.emit( | |
| 'error', | |
| new Error('Protocol error: Unexpected CONTINUATION without start'), | |
| ); | |
| return void this.#close( | |
| Frame.protocolErrorClose( | |
| PROTOCOL_ERROR_SUBTYPES.COMMON, | |
| this.#isClient, | |
| ), | |
| ); | |
| const error = new Error('Protocol error: Unexpected CONTINUATION without start'); | |
| this.emit('error', error); | |
| const frame = Frame.protocolErrorClose( | |
| PROTOCOL_ERROR_SUBTYPES.COMMON, | |
| this.#isClient, | |
| ); | |
| return void this.#close(frame); |
| static close(code = 1000, reason = '') { | ||
| if (code === null || code === undefined) { | ||
| const payload = Buffer.alloc(0); | ||
| return new this(true, OPCODES.CLOSE, false, payload, null); |
There was a problem hiding this comment.
| return new this(true, OPCODES.CLOSE, false, payload, null); | |
| return new Frame(true, OPCODES.CLOSE, false, payload, null); |
| static emptyPingBuffer(isClient = false) { | ||
| const buf = isClient ? Buffer.from(CLIENT_EMPTY_PING) : EMPTY_PING; | ||
| if (isClient) crypto.randomBytes(4).copy(buf, 2); | ||
| return buf; | ||
| } |
There was a problem hiding this comment.
It looks like we can preallocate this buffer to avoid calling method
| } = require('./constants.js'); | ||
| const { Result } = require('./utils/result.js'); | ||
|
|
||
| class Frame { |
There was a problem hiding this comment.
Think about naming improvement for this class static methods, it looks like all those methods are factories, so createPong will be better and createCloseError will be better than errorClose
| const { Connection } = require('../../../lib/websocket/connection.js'); | ||
| const { Frame } = require('../../../lib/websocket/frame.js'); | ||
| const { | ||
| OPCODES, | ||
| CLOSE_TIMEOUT, | ||
| } = require('../../../lib/websocket/constants.js'); | ||
| const { FrameParser } = require('../../../lib/websocket/frameParser.js'); | ||
| const { MockSocket } = require('../utils/mockSocket.js'); |
There was a problem hiding this comment.
Such long /../ constructions are not ok, let's find alternative way
There was a problem hiding this comment.
This will be better require('../../../metacom.js'); but I'll propose something better later, need a time to clone and check repo locally
#476
npm t)npm run fix)