0

TL;DR: Sending "Deflate" compressed data to a client over a web socket causes issues that are hard to track down. Is sending "Deflate" compressed data over a web socket possible?

I have an application that uses Flashlight VNC that has been updated to use web sockets. In an attempt to make it more performant, I'm attempting to compress the data before it hits the Flash application. The VNC client bombs immediate after the handshake (when the compression starts).

Handshake:

'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'Host: ' + hostport + '\r\n' +
'Origin: ' + url.slice(0, url.indexOf("/", 10)+1) + '\r\n' +
'Sec-WebSocket-Protocol: ' + 'base64' + '\r\n' +
'Sec-WebSocket-Key1: ' + key1 + '\r\n' +
'Sec-WebSocket-Key2: ' + key2 + '\r\n\r\n';

Compression code (Scala)

def deflate3(str:String):String = {
    val data = str.getBytes
    val deflater = new Deflater
    deflater.setInput(data)

    val outputStream = new ByteArrayOutputStream(data.length)
    deflater.finish
    val buffer = new Array[Byte](1024)
    while(!deflater.finished) {
      val count = deflater.deflate(buffer)
      outputStream.write(buffer, 0, count)
    }
    outputStream.close
    outputStream.toString
  }

The web socket send (embedded Jetty 8/Scala):

def onMessage(message:String) {
      try {
        val compressed = deflate(message)
        serverSocket.connection.sendMessage(compressed)
      } catch {
        case e : Exception => {
          println(e.getCause)
        }
      }
    }
binarygiant
  • 6,362
  • 10
  • 50
  • 73

1 Answers1

2

There are 2 options:

  1. Send a binary WebSocket message (WebSocket text messages must contain UTF8 encoded payload)
  2. Deploy a WebSocket server that implements permessage-deflate WebSocket extension. This will transparently compress WebSocket payload (both text and binary) for browsers that support permessage-deflate (currently only Chrome)
oberstet
  • 21,353
  • 10
  • 64
  • 97