alanshaw / alanshaw/stream-to-it

Add option not to destroy duplex stream when either the source or sink iterable completes

Đang mở
#10 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
TypeScript
Star
19
Fork
7
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

(First of all, `stream-to-it` and `it-pipe` are amongst my favourite NPM packages: My code would've been really complicated had you not made these packages available, so thank you so much!)

I'm implementing a WebSocket-based protocol using [`ws`](https://www.npmjs.com/package/ws). `ws` offers a duplex stream to communicate with the peer and I'm wrapping that stream in a "duplex iterable" (generated by `duplex()`), which I pass to `it-pipe`.

The code mostly works as expected, but I'm running into two related issues:

- If there's a `break` in the loop, Node.js would call `duplex.destroy()`, [which will cause `ws` to close the connection abruptly](https://github.com/websockets/ws/issues/1811).
- If the duplex' sink completes normally, Node.js would call `duplex.end()`, which will cause `ws` to close the connection normally -- Even if we're waiting for messages from the source. For example, the protocol I'm implementing sends messages that must be acknowledged by the peer, so if we're done sending messages we should still keep the connection open to receive outstanding ACKs.

I think both issues could be solved if `duplex()` supported an option that wouldn't call `destroy()`/`end()` on the underlying stream (maybe as a pass-through stream). That'd allow me to do something like this on the server:

```javascript
const wsDuplex = WebSocket.createWebSocketStream(ws);
try {
await pipe(loadMessages, duplex(wsDuplex, {allowClosing: false}), processAcknowledgements)

// If we get to this point, processAcknowledgements() must've ended the loop
ws.close(1000, 'All good')
} catch (err) {
ws.close(1008, 'Something went wrong')
}
```

(`duplex.end()` will still be called when the connection is closed. OTOH, the example above is overly simplified: I'd probably have to use an `AbortableController` to signal the source of the duplex iterable when the client closes the connection.)

Thoughts?

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.