Bug 55639 - Add Drawboard Websocket Example
Summary: Add Drawboard Websocket Example
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Examples (show other bugs)
Version: trunk
Hardware: All All
: P2 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-07 23:16 UTC by Konstantin Preißer
Modified: 2013-10-11 13:39 UTC (History)
0 users



Attachments
Patch to add the Drawboard example (91.99 KB, patch)
2013-10-07 23:16 UTC, Konstantin Preißer
Details | Diff
Patch to add the Drawboard example (115.60 KB, patch)
2013-10-07 23:23 UTC, Konstantin Preißer
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Konstantin Preißer 2013-10-07 23:16:40 UTC
Created attachment 30909 [details]
Patch to add the Drawboard example

Hi,

I would like to add this Drawboard example to Tomcat's Websocket examples.

It is a page where you can draw with your mouse or touch input (using different colors) and everybody else which has the page open will immediately see what you are drawing.
If someone opens the page later, they will get the current room image (so they can see what was already drawn by other people).

It uses asynchronous sending of messages so that it doesn't need separate threads for each client to send messages (this needs NIO or APR connector to be used).
A "Room" (where the drawing happens) has a dedicated thread because the actions which are done in one Room are single-threaded (like drawing to a BufferedImage). If multiple rooms were used, then each Room would have its own dedicated thread (but currently only one Room is implemented).

When you open the page, first you will receive a binary websocket message containing the current room image as PNG image. After that, you will receive string messages that contain the drawing actions (line from x1,y1 to x2,y2).
Note that it currently only uses simple string messages instead of JSON because I did not want to introduce a dependency on a JSON lib.

It uses synchronization mechanisms to ensure that the final image will look the same for every user, regardless of what their network latency/speed is - e.g. if two user draw at the same time on the same place, the server will decide which line was the first one, and that will be reflected on every client.

What do you think?
Comment 1 Konstantin Preißer 2013-10-07 23:23:32 UTC
Created attachment 30910 [details]
Patch to add the Drawboard example

Sorry, I forgot to replace tabs with spaces and to add a required file.
(And I don't know why my TortoiseSVN sometimes includes every .java file twice...)
Comment 2 Mark Thomas 2013-10-08 13:52:43 UTC
Trunk (a.k.a. 8.0.x) is Commit-the-Review so go for it. So is 7.0.x for that matter, but I'd recommend against an immediate back-port. Get everything sorted in 8 and then back-port.
Comment 3 Konstantin Preißer 2013-10-08 16:12:37 UTC
(In reply to Mark Thomas from comment #2)
> Trunk (a.k.a. 8.0.x) is Commit-the-Review so go for it. So is 7.0.x for that
> matter, but I'd recommend against an immediate back-port. Get everything
> sorted in 8 and then back-port.

OK, thank you.

This has been fixed in trunk and will be included in 8.0.0-RC4 onwards.

I'm leaving the bug open against 7.0.x to look at backporting later.
Comment 4 Christopher Schultz 2013-10-08 16:56:19 UTC
Is there any reason to bother sending a PNG image to begin with? Why not just store all the mutations (i.e. draw commands) on the server and send those to the clients when they connect? If you did that, you could also avoid performing any AWT operations on the server.

I suppose as a demo it's nice to see how to handle both binary and text-based data in one example.
Comment 5 Konstantin Preißer 2013-10-08 17:06:34 UTC
Hi Christopher,

(In reply to Christopher Schultz from comment #4)
> Is there any reason to bother sending a PNG image to begin with? Why not
> just store all the mutations (i.e. draw commands) on the server and send
> those to the clients when they connect? If you did that, you could also
> avoid performing any AWT operations on the server.
> 
> I suppose as a demo it's nice to see how to handle both binary and
> text-based data in one example.

The reason for sending a PNG at the beginning is because otherwise the server would need to store a huge amount of draw commands so that the client can reconstruct the generated image (because you can never remove a drawed path - you can only overwrite them with your own). This would need a lot of CPU usage at the client and a lot of space on the server.
Also the server would need some logic to detect if a previously draw command is not needed because it is completely overlapped with other draw commands, etc.

Therefore I chose to have a current representation of the room image at the server which is sent to the clients at the start of a session.
Comment 6 Konstantin Preißer 2013-10-11 13:39:18 UTC
This has been fixed in 7.0.x and will be included in 7.0.46 onwards.