Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Jetty9 websocket design

Inline ...

On Thu, May 30, 2013 at 8:06 AM, Nils Kilden-Pedersen <nilskp@xxxxxxxxx> wrote:
Thanks for the detailed answer. I have a few questions and comments inline.

Now, internally to Jetty, the WebSocketServlet has notified the HTTP handling that the HTTP connection handling is now a WebSocketConnection.
The WebSocketConnection is setup with the WebSocket Endpoint

The Open WebSocket:
At this point the RFC6455 state transitions from CONNECTING to OPEN.
The local WSE is notified that the Session is now open.
The JIOE (Jetty I/O Endpoint) now does its Async/NIO handling of read and write interests and notifying the WebSocketConnection when the physical connection is capable of doing a read or a write.

Is this a single thread, multiple, or configurable? Meaning the async selector?

Each connection's Endpoint handling is handled via a single Thread obtained from the Server thread pool.
Most events notified back to the end user's local WebSocket implementation are on the same Thread.
However, starting with 9.1 (in active development), those endpoints that register an interest in receiving messages as InputStream (BINARY messages) or Reader (TEXT / UTF8 messages) will have the stream dispatched to the Local WebSocket Endpoint on a different thread.
 
 
If a read, it fills up an input buffer and parses what it can.
The Parser notifies its IncomingFrames on each frame encountered, which goes through the extension stack and eventually hits the WSE.
If its a write, the Connection's outgoing queue of frames is used to create a output buffer via the Generator.

At this point, the Thread that is handling the JIOE side is the same thread that Jetty pulled from the ThreadPool for the HTTP handling.
When the WebSocket Connection gets its read/write events it will continue to use that same thread to parse, send the frame through the extension stack, and hit the EventDriver, and eventually the WSE.
When the WSE gets the event for say a Text message, then its actually operating on the same Thread that the JIOE is using.
When a JIOE event to write is detected, the same Thread is used to generate and write to the network.

Memory consumption is not constant with WebSocket, due to the nature of the message based (not streaming) WebSocket protocol.

Buffering? Is this handled per connection or system wide, e.g. a buffer pool?

We use java.nio.ByteBuffers extensively within Jetty 9.
Each jetty server instance has its own org.eclipse.jetty.io.ByteBufferPool instance that all connectors, connections, and thread on that server share.
(Curious note, it is possible to have multiple jetty server instances per JVM, but that's an atypical configuration)

 

Performance with Jetty 9.0.3:
We've done some simple (really simple) load testing on WebSockets.
On a simple test of 1000 active WebSockets we got an average rate of 200,000 messages a second per socket. 
But we need MUCH more testing here, along with paying attention to memory and CPU, not just I/O.
The cometd project has already embraced Jetty 9's WebSocket and have been testing the performance from their point of view, while they have some concerns with memory (the jetty websocket implementation seems to have frequent, but small, GC behavior), overall they are happy with what they see.

Have you looked into direct memory buffers? They seem ideal for this sort of thing.

Where appropriate we use direct ByteBuffers already, however with the various extensions in the mix, it is often not possible to carry that direct ByteBuffer all the way through from the Local WebSocket Endpoint down to the network bytes layer.
 
 

The future of WebSocket on Jetty 9.
We are close to completion on our implementation of JSR-356 (the javax.websocket standard API).
It will likely show up in Jetty 9.1 (but this isn't fully decided yet)

What's the alternative? 9.0 or 9.2?

Since this will introduce a new behavior, it will certainly not be part of 9.0.x
It is almost certain to be part of 9.1 (likely along with the Servlet API 3.1 effort)
 
 

It brings a few nice things to the Jetty side API as well.
 * The WebSocketPolicy.setMaxMessage() is split up between text and binary now.
 * Support for streaming messages has been added 
   - you can write a message with an OutputStream or Writer now.
   - you can receive InputStream or Readers (one for each message) on your annotated WSE's now
 * The RemoteEndpoint (how you write to a remote WSE) has some guards to notify you if you abuse the message writing in a multi-threaded environment.
   - Note: the RemoteEndpoint operates in a similar way, threading wise, as a OutputStream (in other words, it is not advisable to attempt to write from multiple threads)

Once we get a stable build with JSR-356 out into the hands of our users, we can start to tackle various performance testing and concerns.

Hope this rambling post helped...

Very much, yes. Thanks.

Glad to help 

Back to the top