achingbrain / achingbrain/webtransport-echo-server
Read and written chunks not interleaved with bidirectional streams on the client side
- Dominant language
- JavaScript
- Stars
- 3
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
Hi Alex,
Thanks a lot for the great sample here. It works great but I have a question regarding how packets are expected to be exchanged in the case of a bi-directional stream.
I've added some logs to your JavaScript client code and I see the following:
- both `writeData` and `readData` promises are started at the same time and are supposed to work simultaneously
- chunks start being received within `readData` only after the `for` loop in `writeData` exited, meaning that all the chunks were sent
My understanding is that the code below (same as yours with log messages) should log interleaved reads and sent:
```
const CHUNKS = 1024
const CHUNK_LENGTH = 1024
async function main () {
// dial the echo server
const transport = new WebTransport('https://127.0.0.1:8080', {
serverCertificateHashes: [{
algorithm: 'sha-256',
value: Uint8Array.from(atob('gI314FM1JXi9vI2oPA2UbqE3C7yM0vr3vhnQ+H3Lq78='), (m) => m.codePointAt(0))
}]
})
// wait for the connection to become established
await transport.ready
// create a bidirectional echo stream
const stream = await transport.createBidirectionalStream()
// count how many bytes have been received
let received = 0
// write and read data simultaneously
await Promise.all([
// write data
async function writeData () {
console.log(`[writeData] start`)
const writer = await stream.writable.getWriter()
for (let i = 0; i < CHUNKS; i++) {
await writer.ready
const buf = Uint8Array.from(new Array(CHUNK_LENGTH).fill(0))
writer.write(buf).catch(() => {})
console.log(`[writeData] wrote ${i*CHUNK_LENGTH} bytes`)
}
console.log(`[writeData] closing writer`)
await writer.close()
console.log(`[writeData] writer closed`)
console.log(`[writeData] stop`)
}(),
// read data
async function readData () {
console.log(`[readData] start`)
const reader = await stream.readable.getReader()
while (true) {
const result = await reader.read()
if (result.done) {
return
}
received += result.value.byteLength
console.log(`[readData] read ${received} bytes`)
}
console.log(`[readData] stop`)
}()
])
console.info('done send and read', received, 'bytes of', CHUNKS * CHUNK_LENGTH)
}
main().catch(err => {
console.error(err.stack)
})
```
But the logs shown instead reveal that the JS client writes all of its chunks before processing the echoed data from the server (output truncated in three images):
I tried removing the `await writer.close()` line but got the same result. And interestingly, logging packets with Wireshark show that the server echoes back the chunk while still receiving packets from the client.
I wonder if I'm missing something here and this is expected, and would be glad to have your opinion :-)
Thanks again for the code sample, this is very useful to get a better understanding of how WebTransport works!
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the JavaScript client sample's writeData and readData functions, especially the bidirectional stream setup and writer.ready calls. Run the sample with the provided logging and compare application logs with the observed WebTransport behavior. Done means establishing whether the lack of interleaved reads is expected and documenting or isolating the cause.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100