how to decode binary on websocket

1,275 views
Skip to first unread message

David Beckwith

unread,
Jan 2, 2012, 11:53:49 PM1/2/12
to Aleph
I tried sending a jpg image through a websocket using the HTML5
FileReader object (reader.readAsArrayBuffer(f)).

The first 1010 bytes transferred perfectly. 1010 is the size of the
first Java.nio.HeapByteBuffer in the
gloss.data.bytes.core.MultiBufferSequence. After that, nothing in the
hexdumps seems to match.

I'd like to simply decode the binary and write it to a file, but the
image data seem to have been corrupted after the first ByteBuffer.

So my questions are:

1. Is there an obvious and easy way to decode and write binary to a
file from one of Aleph's websocket handlers?
2. is there a non-obvious hard way to that?

Any tips or tricks would be most appreciated.

BTW, it would be nice if you could just do

(receive ch
#(clojure.java.io/copy % (as-file destination)))

Anyway, here is my latest hackings below..... thanks so much for the
help in advance.

** The client-side Javascript code.

var handle_file_select = function(evt) {
evt.stopPropagation();
evt.preventDefault();

var files = evt.dataTransfer.files; // FileList object.

// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')){ continue; }
var reader = new FileReader();
reader.onload = (function(the_file) {
return function(e){
ws['upload'].send(e.target.result);
}
})(f);
reader.readAsArrayBuffer(f);
}// for f
}// handle_file_select


; The server-side code.

(ns chat.upload
(:use lamina.core)
(:use aleph.http)
(:use gloss.io))

(defn upload-handler [user-ch handshake]
(receive user-ch
(fn [client_id]
(let [dest (str "/var/www/static/original/" client_id "/
sample.jpg")]
(receive user-ch
(fn [msg]
(let [fout (-> dest
java.io.FileOutputStream. .getChannel)
buf (contiguous msg)
dbuf (java.nio.ByteBuffer/allocateDirect(.remaining
buf))]
(do
(-> dbuf (.put buf) .flip)
(.write fout dbuf)
(.close fout)))))))))

(def s3 (start-http-server upload-handler {:port 9013 :websocket
true}))

Zach Tellman

unread,
Jan 3, 2012, 12:10:51 AM1/3/12
to alep...@googlegroups.com
Hi David,

I believe this is an issue with the bit-masking across multiple
buffers. I've pushed a fix to 0.2.1-SNAPSHOT, can you tell me if it
resolves the issue? If not, I'll get a comparable setup on my own
system so I can look into this more thoroughly.

Zach

David Beckwith

unread,
Jan 3, 2012, 9:47:09 PM1/3/12
to Aleph
Hey success!~~~

:D

Cheers!

Zach Tellman

unread,
Jan 3, 2012, 10:15:13 PM1/3/12
to alep...@googlegroups.com
Glad to hear it. As I've said elsewhere, the upcoming release of
Netty adds support for the newer (hybi) websocket protocol, and will
bring and end to these sorts of problems. My implementation of the
newer protocol was meant to be a short-term hack for people using
upstream versions of Chrome, but I didn't count on Netty 3.3.0 taking
quite so long to come out. Sorry for the issue, let me know if you
encounter any others.

Zach

tomoj

unread,
Jan 9, 2012, 11:25:10 PM1/9/12
to Aleph
With the latest snapshot I was getting ArrayIndexOutOfBoundsException:
4 (on the mask array) when receiving long messages.

The fix seems to be (rem (inc ary-idx) 4) on line 111 of
aleph.http.websocket.protocol (the recur in mask-buffers). I don't
understand what that code is actually doing, but this fix makes sense
given the error, and so far so good.
Reply all
Reply to author
Forward
0 new messages