DEFLATE preserve LZ77 sliding window

I am trying to implement my own WebSocket client. I successfully was able implement everything I need, except compression extension. I use inflate (decompressing) and deflate (compressing).

As testing setup I have create small NodeJS WebSocket server, after connection once a second, server is sending Hello string.

import ws from "ws";
import http from "http";

let server = http.createServer();
var wss = new ws.Server({ server: server, perMessageDeflate: true });

wss.on("connection", function (ws) {
  console.log("new connection");

  setInterval(() => {
    console.log("Sending Hello");
    ws.send("Hello");
  }, 1000);
});

server.listen(8000);

On rust side I correctly receive message payload and successfully inflate it:

use inflate::inflate_bytes;

let Ok(payload) = inflate_bytes(&payload) else {
    println!("Received un-inflatable message: {:?}", payload);
    return;
};

But this works correctly only for the first Hello, all following messages are throwing error at inflate.

As I understand I need to use same LZ77 sliding window that I have used for compressing/decompressing previous messages, but I cant find any ready crate for this, is there any at all ?

Also if there is such crate, is it possible to use that implementation in threads (where multiple threads at the same time decompress/compress different messages) ?

Those crates look a bit old, but they're probably fine. You are almost certainly looking for inflate::InflateStream - Rust and the equivalent to keep the state, (though it's a little more work to reliably decode, take care to read the docs!)

But as I understand this is not thread safe solution, and so to use it in multiple threads I would have to wrap this stream in Mutex and block each time I would like to compress/decompress?

If you're trying to, you're probably using it wrong anyway? You just read those bytes, and that already needed a mut handle, which ensures that you're protected (since only one mut ref can exist at a time)

Not to mention, decompressing has to happen in the same order as it was compressed, so it doesn't make sense to split it over threads.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.