Mark,

Sorry for the delay in responding. I am working on this project in my spare
time.
That I was missing something wasn't the question.   The question was what.

I think I figured it out, but wanted to follow up for two reasons. One is
the benefit  of
others in my situation (this stuff is still pretty sparsely documented) and
two, there are
some further points that I am still not sure about and hope someone could
comment on.

Because of security concerns, the transmission of large messages over a
WebSocket
has different semantics for in- (from client to server) and out-bound (from
server to
client) messages.  Since it is up to the client to establish a WebSocket
session, the
server is free to send a message of any size by simply calling

javax.websocket.RemoteEndpoint.sendText(String message)

I imagine client implementations may differ in how they deal with
particularly large
payloads, but anything reasonable will be transmitted and received just
fine and at
lest as defined by the JSR 356, sizes of up to unsigned long are supported.

The same is not the case for the inbound messages.  And the way Tomcat
handles
large messages is neither standard, nor at this point (well) documented.
Here's what
I have discovered:

The websocket.send(String) method takes a payload of any size. (There may
be further nuances in cases when client generates inbound traffic faster
than the
network is able to transmit it, but at least when bufferedAmount == 0, this
statement is
true.)

However, the server implementation is free to pick the maximum size of a
payload
that it is willing to receive as a whole.  Tomcat designers chose that size
to be 125
bytes.  Reasonable number given the particulars of the wire level protocol,
but not
one defined in the standard.

In other words, if I want to receive inbound message that can be longer
than 125
bytes, I need to configure the server side session with a message handler
that
implements
javax.websocket.MessageHandler.Partial

The implementation will partition the message into fragments of up to 8192
characters
and make them available to the app code via the implementation of
onMessage(String part, boolean last) method.

It appears that there's also a talk of exposing the inbound message via a
Reader <http://www.oracle.com/technetwork/articles/java/jsr356-1937161.html>but
that's not in Java EE 7.

So, just as a specific example, my implementation looks like the following:

public class FermiMessageHandler implements MessageHandler.Partial<String> {

    private Session session;
    private int maxMessageSize = 20000;
    private StringBuilder messageBuffer = new StringBuilder(maxMessageSize);

    FermiMessageHandler(Session session) {
        this.session = session;
    }

    @Override
    public void onMessage(String msgPart, boolean last) {
        if( messageBuffer.length() + msgPart.length() > maxMessageSize) {
            session.close(new
CloseReason(CloseReason.CloseCodes.CLOSED_ABNORMALLY, "Message is too
long");
        }
        else {
            messageBuffer.append(msgPart);
            if (last) {
                String message = messageBuffer.toString();
                // We have a complete message.  Do something with it.
                messageBuffer.setLength(0);
            }
        }
    }
}

Thanks,
-Igor.



On Wed, Sep 18, 2013 at 1:12 AM, Mark Thomas <ma...@apache.org> wrote:

> On 18/09/2013 06:19, Igor Urisman wrote:
> > Dear All,
> >
> > I am looking for help in understanding why the size of the inbound
> > WebSocket message is limited to 125 bytes.
>
> It isn't, at least not by Tomcat.
>
> >  I realize that this may not
> > even be the right place for my question, but am still hoping for a clue.
> >
> > From looking at the RFC 6455, Sec. 5.2 Base Framing Protocol, I am making
> > two conclusions:
> >
> > 1. There's nothing in it to suggest a payload length asymmetry between
> > inbound and outbound messages.  Yet, although I am able to send very
> large
> > messages to the browser, an attempt to send anything over 125 bytes
> results
> > in error and a connection shutdown.  (I tried FF and Chrome on a Mac).
> >
> > 2. It's easy to see from the wire protocol why 125 is the simplest
> payload
> > length but other sizes up to unsigned 64 bit int are supported.  So,
> > browser's failure to transmit more than 125 bits indicates both, the most
> > restrictive payload size AND lack of support for fragmented messages.
> >
> > The error that FF gives reads "The decoded text message was too big for
> the
> > output buffer and the endpoint does not support partial messages" which
> to
> > me reads like they are saying that Tomcat did not indicate during
> handshake
> > that it accepts multi-part messages.  True?
>
> False. There is nothing in the handshake that allows one end not to
> support multi-part messages nor to limit the maximum message length.
>
> That looks like a client side issue to me. Maybe you need to make the
> client side output buffer bigger.
>
> Tomcat's web socket support (client and server) has been tested with the
> Autobahn testsuite that includes tests with significantly larger
> messages than 125 bytes both as single frames and as multiple frames.
> >
> > I can't speak for others, but for my project 125 bytes is unacceptably
> > small.  So, fundamentally what I need to know is this: do I need to
> > implement my own fragmenting or am I missing something?
>
> You are missing something. No idea what since you haven't provided any
> details of your client side implementation.
>
> Mark
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>

Reply via email to