max-mapper / websocket-stream

websockets with the node stream API
BSD 2-Clause "Simplified" License
667 stars 114 forks source link

Object mode being optional #72

Open mcollina opened 9 years ago

mcollina commented 9 years ago

In 2.0.0 the websocket-stream is now running in object mode. I see why this is a good default, as it allows a consistent behavior on both ends when sending data (the framing is done by ws).

How about making this setting optional? As an example, I would want to disable this for mqtt.js.

mafintosh commented 9 years ago

Good point. Maybe we should have objectMode exposed by a .obj() method like we do in through2 instead?

var ws = websocketStream.obj() // object mode stream
var ws = websocketStream() // binary stream
max-mapper commented 9 years ago

IMO object mode is a better default, how about just supporting {objectMode: false}

yoshuawuyts commented 9 years ago

I think .obj() would be nice for consistency with through2 / from2 despite object mode being the objectively better default.

mcollina commented 9 years ago

I'm in for objectMode: false, it's definitely safer to assume objectMode: true: websocket does its own fragmentation and the like.

@yoshuawuyts The only case when this is bad is when sending big buffers (files!) or with a streaming binary protocol (like MQTT).

max-mapper commented 9 years ago

yea since websockets dont have backpressure its kind of a hack to put a stream interface on top of websockets anyway so I don't think strictly adhering to node core stream semantics is a high priority

serapath commented 7 years ago

Hey :-) Is objectMode supported now? I only found this issue that touches the topic. It is not listed in the readme, but it mentions:

Options can be passed in as the third or second argument - WebSocket(address, [protocols], [options])

I'm trying to send objects in electron from a render procees to the main process.

I tried to supply options { objectMode: true } but when i send data

// renderer
var ws = require('websocket-stream')('http://127.0.0.1',{ objectMode: true })
ws.write({ foo: 'bar' })
ws.end()

i receive

// main
var wss = websocket.createServer({ server: httpServer }, handler)
function handler (client) {
  client.on('data', function (data) {
    console.log(data) // <Buffer 5b 6f 62 6a 65 63 74 20 4f 62 6a 65 63 74 5d>
    console.log(data.toString) // "[object Object]"
  })
}

Should i alwasy call JSON.stringify(data) before the client sends and then JSON.parse(data) on the server? I'm not planning to send anything that is not an object, so it would be very convenient if objectMode would somehow work.

mcollina commented 7 years ago

The streams works in objectMode, but it can only move buffers or strings. You do not have to check the length of the transmitted packet etc before decoding. Object encoding/decoding is left to you to do.