Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Avoiding WebSocket.OnBinaryMessage aggregation, or using WebSocket.onFrame

With a little trial-and-error, and some time looking at RFC 6455, I
think that I've mostly answered my own question. My class now looks
something like this (this is a greatly simplified version):

abstract public class MyWebSocket implements WebSocket,
WebSocket.OnTextMessage, WebSocket.OnFrame {
    private static final byte CONTINUATION_FRAME = 0;
    private static final byte BINARY_FRAME = 2;

    private boolean processingBinaryFrame;

    @Override
    public boolean onFrame(byte flags, byte opcode, byte[] data, int
offset, int length) {
        if (opcode == BINARY_FRAME || (processingBinaryFrame && opcode
== CONTINUATION_FRAME)) {
            processingBinaryFrame = true;
            onBinaryMessage(data, offset, length);
            return true;
        }
        return false;
    }

    @Override
    public void onHandshake(FrameConnection connection) {
        // I don't think we need to do anything special here
    }

    @Override
    public void onMessage(String data) {
        processingBinaryFrame = false;
        onTextMessage(data);
    }

    protected void onBinaryMessage(byte[] data, int offset, int length) {
        throw new IllegalArgumentException(getClass() + " cannot
receive a binary message.");
    }

    protected void onTextMessage(String data) {
        throw new IllegalArgumentException(getClass() + " cannot
receive a text message.");
    }
}

Other than the poor form of hard-coding the CONTINUATION_FRAME and
BINARY_FRAME values when there are FrameConnection methods to check
for those opcodes, is there anything wrong with my approach? Are there
edge cases that my implementation misses?

Thanks,
Brandon

On Thu, Sep 13, 2012 at 11:36 AM, Brandon Mintern <mintern@xxxxxxxxxxx> wrote:
> I'm building an application using Jetty WebSockets that sends a very
> large stream of binary from the client to the server. That is, it's a
> streaming upload that involves several Javascript calls to
> connection.send(block), where each block is an ArrayBuffer of up to 1
> MB in size. This is done completely asynchronously, so that a
> subsequent call to connection.send does not occur until a prior one
> completes successfully.
>
> On the other end, I've (so far) implemented OnBinaryMessage and
> OnTextMessage. It was working pretty well, but during testing I was
> seeing messages to the effect of "binary frame aggregation disabled."
> During onOpen, I tried calling connection.setMaxBinarySize(2048*512),
> but this failed as well. When I doubled that size, it worked, but it
> seems silly to allocate 2 MB when I might need as little as 512 bytes,
> and it definitely feels like I'm solving the wrong problem at this
> point.
>
> On the server side, I really don't need any aggregation at all; I'm
> simply writing data[offset:offset+length] to a PipedOutputStream,
> where the input side is read by another thread. What is the best way
> to simply pass off binary data in this way, without performing any
> aggregation? It seems that I need to implement WebSocket.OnFrame, but
> I could not find any helpful documentation for it. Can I simply return
> false if it is a text frame, and handle it if it is a binary frame?
> How do I check opcode to determine whether it is binary? If I'm
> handling binary messages using an onFrame method, do I no longer need
> to implement OnBinaryMessage? Do I need to do anything special with
> the flags argument? When is onHandshake called? Is there anything that
> must be done there?
>
> Thank you for any insight you can give me. If you can simply point me
> to documentation (the source as downloaded via maven has none), I'm
> happy to dig into it myself.
>
> Cheers,
> Brandon


Back to the top