ohmm
Class ImageServer

java.lang.Object
  extended by ohmm.ImageServer

public class ImageServer
extends java.lang.Object

HTTP multipart/x-mixed-replace image server.

The source frames are provided via the hook updateImage(java.awt.image.BufferedImage), which also sets the width and height. The compression type, compression quality (if appliccable), and maximum served frames per second are controlled by URL query parameters "fmt" (string, e.g. "jpeg" or "png"), "fps" (float), and "qual" (int, 0=min, 100=max), respectively. They default to defFmt, defFPS, and defQual if the query params are not given.

Key and mouse events are collected from the client and made available in image coordinates via the hooks handleKey(char) and handleMouse(int, int, int, int).

Tested with Chrome and Safari. Firefox might or might not work (Mozilla bug 625012). On any browser, non-alphanumeric keycodes may differ from Java std.

The server knows about the following request paths:

Once the server is running, you can connect to it from a remote host by bringing up e.g. Google Chrome and browsing to the url


 http://ADDR:PORT/server.html

 
where ADDR is the IP address and PORT the listening port of the server. You can further control the image format, framerate, and quality like this:

 http://ADDR:PORT/server.html?fmt=jpg&fps=10&qual=95

 

Author:
Marsette Vona

Nested Class Summary
protected  class ImageServer.ExchangeState
          Wraps an HttpExchange with some derived values.
 
Field Summary
 boolean dbg
          Debug next server frame.
static java.lang.String DEF_FMT
          Default defFmt.
static float DEF_FPS
          Default defFPS.
static int DEF_PORT
          Default TCP listen port.
static int DEF_QUAL
          Default defQual.
static int DEF_STOP_SEC
          Default stop(int) delay seconds.
 java.lang.String defFmt
          Default ImageIO format name.
 float defFPS
          Default max framerate.
 int defQual
          Default image quality in the range 0 (min) to 100 (max).
static int EVENT_FLAG_ALTKEY
          Event flags for handleMouse(int, int, int, int).
static int EVENT_FLAG_CTRLKEY
          Event flags for handleMouse(int, int, int, int).
static int EVENT_FLAG_LBUTTON
          Event flags for handleMouse(int, int, int, int).
static int EVENT_FLAG_MBUTTON
          Event flags for handleMouse(int, int, int, int).
static int EVENT_FLAG_RBUTTON
          Event flags for handleMouse(int, int, int, int).
static int EVENT_FLAG_SHIFTKEY
          Event flags for handleMouse(int, int, int, int).
static int EVENT_LBUTTONDBLCLK
          Event types for handleMouse(int, int, int, int).
static int EVENT_LBUTTONDOWN
          Event types for handleMouse(int, int, int, int).
static int EVENT_LBUTTONUP
          Event types for handleMouse(int, int, int, int).
static int EVENT_MBUTTONDBLCLK
          Event types for handleMouse(int, int, int, int).
static int EVENT_MBUTTONDOWN
          Event types for handleMouse(int, int, int, int).
static int EVENT_MBUTTONUP
          Event types for handleMouse(int, int, int, int).
static int EVENT_MOUSEMOVE
          Event types for handleMouse(int, int, int, int).
static int EVENT_RBUTTONDBLCLK
          Event types for handleMouse(int, int, int, int).
static int EVENT_RBUTTONDOWN
          Event types for handleMouse(int, int, int, int).
static int EVENT_RBUTTONUP
          Event types for handleMouse(int, int, int, int).
protected  java.util.concurrent.ExecutorService executor
          The internal transaction executor.
static int HTTP_FORBIDDEN
          HTTP response codes
static int HTTP_NOT_FOUND
          HTTP response codes
static int HTTP_OK
          HTTP response codes
protected  int imageClients
          Number of clients to which we're currently serving images.
static java.lang.String MIME_BOUNDARY
          MIME multipart boundary
 java.io.PrintStream msgStream
          Strems for messages and warnings, or null to disable.
static java.text.DecimalFormat NF
          Number format for printouts.
protected  boolean oneClient
          Whether to limit serving images to one client.
 int port
          Server TCP listen port.
protected  com.sun.net.httpserver.HttpServer server
          The internal server object.
static java.lang.String SERVER_HTML
          Server html file.
 boolean spewMouseMoves
          Whether to output lots of debug messages for mousemove events.
 boolean spewStackTraces
          Whether to dump stack traces on server errors.
 java.io.PrintStream warnStream
          Strems for messages and warnings, or null to disable.
 
Constructor Summary
ImageServer()
          Creates server using DEF_PORT.
ImageServer(int port)
          Creates server.
 
Method Summary
protected  java.io.InputStream getServerHTML()
          Hook to get the html the server sends to the client.
static java.net.InetAddress[] getServerIPs()
          Get the server's non-local IP address(es).
protected  void handleEcho(ImageServer.ExchangeState xs)
          Serves debug echo info.
protected  void handleExchange(com.sun.net.httpserver.HttpExchange xch)
          Dispatches HTTP exchange to one of the handle*(ExchangeState) methods.
protected  void handleImage(ImageServer.ExchangeState xs)
          Serves images.
protected  void handleKey(char c)
          Hook to handle key events.
protected  void handleKey(ImageServer.ExchangeState xs)
          Handles key event requests.
protected  void handleMouse(ImageServer.ExchangeState xs)
          Handles mouse event requests.
protected  void handleMouse(int t, int x, int y, int m)
          Hook to handle mouse events.
protected  void handleServer(ImageServer.ExchangeState xs)
          Serves SERVER_HTML using getServerHTML().
protected  void handleUnknown(ImageServer.ExchangeState xs)
          Handles unknown request paths.
static void main(java.lang.String[] argv)
          Starts a test server.
protected  void msg(java.lang.String m)
          Display a message to msgStream, if any.
protected static long nowMS()
          Returns current time in milliseconds.
 void start()
          Starts server.
 void stop()
          stop(int) delaying DEF_STOP_SEC.
 void stop(int delay)
          Stops server and executor.
protected  java.awt.image.BufferedImage updateImage(java.awt.image.BufferedImage bi)
          Hook called to update the server image.
protected  void warn(java.lang.String m)
          Display a warning to warnStream, if any.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEF_PORT

public static final int DEF_PORT
Default TCP listen port.

See Also:
Constant Field Values

DEF_FMT

public static final java.lang.String DEF_FMT
Default defFmt.

See Also:
Constant Field Values

DEF_FPS

public static final float DEF_FPS
Default defFPS.

See Also:
Constant Field Values

DEF_QUAL

public static final int DEF_QUAL
Default defQual.

See Also:
Constant Field Values

DEF_STOP_SEC

public static final int DEF_STOP_SEC
Default stop(int) delay seconds.

See Also:
Constant Field Values

SERVER_HTML

public static final java.lang.String SERVER_HTML
Server html file.

See Also:
Constant Field Values

HTTP_OK

public static final int HTTP_OK
HTTP response codes

See Also:
Constant Field Values

HTTP_NOT_FOUND

public static final int HTTP_NOT_FOUND
HTTP response codes

See Also:
Constant Field Values

HTTP_FORBIDDEN

public static final int HTTP_FORBIDDEN
HTTP response codes

See Also:
Constant Field Values

MIME_BOUNDARY

public static final java.lang.String MIME_BOUNDARY
MIME multipart boundary

See Also:
Constant Field Values

EVENT_MOUSEMOVE

public static final int EVENT_MOUSEMOVE

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_LBUTTONDOWN

public static final int EVENT_LBUTTONDOWN

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_RBUTTONDOWN

public static final int EVENT_RBUTTONDOWN

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_MBUTTONDOWN

public static final int EVENT_MBUTTONDOWN

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_LBUTTONUP

public static final int EVENT_LBUTTONUP

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_RBUTTONUP

public static final int EVENT_RBUTTONUP

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_MBUTTONUP

public static final int EVENT_MBUTTONUP

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_LBUTTONDBLCLK

public static final int EVENT_LBUTTONDBLCLK

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_RBUTTONDBLCLK

public static final int EVENT_RBUTTONDBLCLK

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_MBUTTONDBLCLK

public static final int EVENT_MBUTTONDBLCLK

Event types for handleMouse(int, int, int, int).

Compatible with OpenCV event types.

See Also:
Constant Field Values

EVENT_FLAG_LBUTTON

public static final int EVENT_FLAG_LBUTTON

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

EVENT_FLAG_RBUTTON

public static final int EVENT_FLAG_RBUTTON

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

EVENT_FLAG_MBUTTON

public static final int EVENT_FLAG_MBUTTON

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

EVENT_FLAG_CTRLKEY

public static final int EVENT_FLAG_CTRLKEY

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

EVENT_FLAG_SHIFTKEY

public static final int EVENT_FLAG_SHIFTKEY

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

EVENT_FLAG_ALTKEY

public static final int EVENT_FLAG_ALTKEY

Event flags for handleMouse(int, int, int, int).

Compatible with OpenCV event flags.

See Also:
Constant Field Values

NF

public static final java.text.DecimalFormat NF
Number format for printouts.


port

public final int port
Server TCP listen port.


defFmt

public volatile java.lang.String defFmt
Default ImageIO format name.


defFPS

public volatile float defFPS
Default max framerate.


defQual

public volatile int defQual
Default image quality in the range 0 (min) to 100 (max).


dbg

public volatile boolean dbg
Debug next server frame.


msgStream

public volatile java.io.PrintStream msgStream
Strems for messages and warnings, or null to disable.


warnStream

public volatile java.io.PrintStream warnStream
Strems for messages and warnings, or null to disable.


spewMouseMoves

public volatile boolean spewMouseMoves
Whether to output lots of debug messages for mousemove events.


spewStackTraces

public volatile boolean spewStackTraces
Whether to dump stack traces on server errors.


imageClients

protected volatile int imageClients
Number of clients to which we're currently serving images.


oneClient

protected volatile boolean oneClient
Whether to limit serving images to one client.


server

protected final com.sun.net.httpserver.HttpServer server
The internal server object.


executor

protected final java.util.concurrent.ExecutorService executor
The internal transaction executor.

Constructor Detail

ImageServer

public ImageServer(int port)
            throws java.io.IOException

Creates server.

You may configure public fields before calling start().

Parameters:
port - the TCP listen port
Throws:
java.io.IOException

ImageServer

public ImageServer()
            throws java.io.IOException
Creates server using DEF_PORT.

Throws:
java.io.IOException
Method Detail

handleExchange

protected void handleExchange(com.sun.net.httpserver.HttpExchange xch)
                       throws java.io.IOException
Dispatches HTTP exchange to one of the handle*(ExchangeState) methods.

Throws:
java.io.IOException

handleEcho

protected void handleEcho(ImageServer.ExchangeState xs)
                   throws java.io.IOException
Serves debug echo info.

Throws:
java.io.IOException

handleServer

protected void handleServer(ImageServer.ExchangeState xs)
                     throws java.io.IOException
Serves SERVER_HTML using getServerHTML().

Throws:
java.io.IOException

getServerHTML

protected java.io.InputStream getServerHTML()
                                     throws java.io.IOException

Hook to get the html the server sends to the client.

Default impl uses getResourceAsStream() to open and return SERVER_HTML.

Throws:
java.io.IOException

handleImage

protected void handleImage(ImageServer.ExchangeState xs)
                    throws java.lang.Exception
Serves images.

Throws:
java.lang.Exception

updateImage

protected java.awt.image.BufferedImage updateImage(java.awt.image.BufferedImage bi)

Hook called to update the server image.

Parameters:
bi - the prior image, if any, else null
Returns:
the new image, if any, else null

Will be called by a server exchange handling thread while synchronized on this ImageServer instance.

Default impl does nothing. Subclasses can override this to provide images. To avoid creating a lot of memory garbage it is recommended to create the image once and then to update it in place on subsequent frames.


handleMouse

protected void handleMouse(ImageServer.ExchangeState xs)

Handles mouse event requests.

Parses the event parameters and then calls handleMouse(int, int, int, int) which can be overridden as desired.


handleMouse

protected void handleMouse(int t,
                           int x,
                           int y,
                           int m)

Hook to handle mouse events.

Parameters:
t - one of the EVENT_* constants
x - the x pixel coordinate of the mouse event
y - the y pixel coordinate of the mouse event
m - bitmask of the EVENT_FLAG_* constants

This is called when the client notifies the server that a mouse event has occured over the image.

Default impl does nothing. Subclasses can override this to take action on mouse events over the client image.


handleKey

protected void handleKey(ImageServer.ExchangeState xs)

Handles key event requests.

Parses the event parameters and then calls handleKey(char) which can be overridden as desired.


handleKey

protected void handleKey(char c)

Hook to handle key events.

Parameters:
c - the key character

This is called when the client notifies the server that a key event has occured over the image.

Default impl does nothing. Subclasses can override this to take action on key events over the client image.


handleUnknown

protected void handleUnknown(ImageServer.ExchangeState xs)
                      throws java.io.IOException
Handles unknown request paths.

Throws:
java.io.IOException

nowMS

protected static long nowMS()
Returns current time in milliseconds.


msg

protected void msg(java.lang.String m)
Display a message to msgStream, if any.


warn

protected void warn(java.lang.String m)
Display a warning to warnStream, if any.


start

public void start()
           throws java.io.IOException
Starts server.

Throws:
java.io.IOException

stop

public void stop(int delay)

Stops server and executor.

Parameters:
delay - seconds to wait for any ongoing exchanges to finish

Call this to bring the server down.


stop

public void stop()
stop(int) delaying DEF_STOP_SEC.


getServerIPs

public static java.net.InetAddress[] getServerIPs()
                                           throws java.io.IOException
Get the server's non-local IP address(es).

Throws:
java.io.IOException

main

public static void main(java.lang.String[] argv)
                 throws java.io.IOException

Starts a test server.

Parameters:
argv - up to one arg is accepted giving the TCP listen port

Serves synthetic images marked with their frame number.

Throws:
java.io.IOException