Skip to content

Commit

Permalink
Issue #1165 - updating documentation with WriteCallback async examples
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
  • Loading branch information
lachlan-roberts committed Oct 10, 2019
1 parent 86e2f5b commit e0f3440
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,53 @@ catch (IOException e)
How to send a Text message in 2 parts, using the partial message support in RemoteEndpoint.
This will block until each part of the message is sent, possibly throwing an IOException if unable to send the partial message.

[[websocket-async-send]]
==== Async Send Message

There are also 4 Async send message methods available:

* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendBytes(java.nio.ByteBuffer,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendBytes(ByteBuffer message, WriteCallback callback)`]
* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendPartialBytes(java.nio.ByteBuffer,boolean,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendPartialBytes(ByteBuffer message, boolean isLast, WriteCallback callback)`]
* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendString(java.lang.String,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendString(String message, WriteCallback callback)`]
* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendPartialString(java.lang.String,boolean,org.eclipse.jetty.websocket.api.WriteCallback)[`RemoteEndpoint.sendPartialString(String message, boolean isLast, WriteCallback callback)`]

All these async send methods use WriteCallback, this allows you to be
notified when the write either succeeds or fails.

[source, java, subs="{sub-order}"]
----
WriteCallback callback = new WriteCallback()
{
@Override
public void writeSuccess()
{
// Notification that the write has succeeded.
}
@Override
public void writeFailed(Throwable x)
{
// Notification that the write has failed.
t.printStackTrace();
}
};
----

The async send methods can be used in a similar way to the blocking
send methods, however the method will return before the message is transmitted,
and you are notified of the final result of the message transmission through
the WriteCallback. The static `WriteCallback.NOOP` can be used to do nothing
on success / failure of the callback.
[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a BINARY message to remote endpoint
ByteBuffer message = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 });
remote.sendBytes(message, callback);
----


[[pingpong]]
==== Send Ping / Pong Control Frame

Expand Down Expand Up @@ -162,139 +209,19 @@ This will block until the message is sent, possibly throwing an IOException if u

To be correct in your usage of Pong frames, you should return the same byte array data that you received in the Ping frame.

[[websocket-async-send]]
==== Async Send Message

However there are also 2 Async send message methods available:

* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendBytesByFuture(java.nio.ByteBuffer)[`RemoteEndpoint.sendBytesByFuture(ByteBuffer message)`]
* link:{JDURL}/org/eclipse/jetty/websocket/api/RemoteEndpoint.html#sendStringByFuture(java.lang.String)[`RemoteEndpoint.sendStringByFuture(String message)`]

Both return a `Future<Void>` that can be used to test for success and failure of the message send using standard http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html[`java.util.concurrent.Future`] behavior.
You can also asynchronously send Ping and Pong frames using the WriteCallback, this will return before the Ping/Pong is
transmitted and notify you of the result in WriteCallback `writeSuccess()` or `writeFailed()`.

[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a BINARY message to remote endpoint
ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 });
remote.sendBytesByFuture(buf);
----
String pingData = "You There?";
ByteBuffer pingPayload = ByteBuffer.wrap(data.getBytes());
How to send a simple Binary message using the RemoteEndpoint.
The message will be enqueued for outgoing write, but you will not know if it succeeded or failed.
String pongData = "Yup, I'm here";
ByteBuffer pongPayload = ByteBuffer.wrap(data.getBytes());
[source, java, subs="{sub-order}"]
remote.sendPing(pingPayload, WriteCallback.NOOP);
remote.sendPong(pongPayload, WriteCallback.NOOP);
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a BINARY message to remote endpoint
ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 });
try
{
Future<Void> fut = remote.sendBytesByFuture(buf);
// wait for completion (forever)
fut.get();
}
catch (ExecutionException | InterruptedException e)
{
// Send failed
e.printStackTrace();
}
----

How to send a simple Binary message using the RemoteEndpoint, tracking the `Future<Void>` to know if the send succeeded or failed.

[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a BINARY message to remote endpoint
ByteBuffer buf = ByteBuffer.wrap(new byte[] { 0x11, 0x22, 0x33, 0x44 });
Future<Void> fut = null;
try
{
fut = remote.sendBytesByFuture(buf);
// wait for completion (timeout)
fut.get(2,TimeUnit.SECONDS);
}
catch (ExecutionException | InterruptedException e)
{
// Send failed
e.printStackTrace();
}
catch (TimeoutException e)
{
// timeout
e.printStackTrace();
if (fut != null)
{
// cancel the message
fut.cancel(true);
}
}
----

How to send a simple Binary message using the RemoteEndpoint, tracking the `Future<Void>` and waiting only prescribed amount of time for the send to complete, cancelling the message if the timeout occurs.

[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a TEXT message to remote endpoint
remote.sendStringByFuture("Hello World");
----

How to send a simple Text message using the RemoteEndpoint.
The message will be enqueued for outgoing write, but you will not know if it succeeded or failed.

[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a TEXT message to remote endpoint
try
{
Future<Void> fut = remote.sendStringByFuture("Hello World");
// wait for completion (forever)
fut.get();
}
catch (ExecutionException | InterruptedException e)
{
// Send failed
e.printStackTrace();
}
----

How to send a simple Binary message using the RemoteEndpoint, tracking the `Future<Void>` to know if the send succeeded or failed.

[source, java, subs="{sub-order}"]
----
RemoteEndpoint remote = session.getRemote();
// Async Send of a TEXT message to remote endpoint
Future<Void> fut = null;
try
{
fut = remote.sendStringByFuture("Hello World");
// wait for completion (timeout)
fut.get(2,TimeUnit.SECONDS);
}
catch (ExecutionException | InterruptedException e)
{
// Send failed
e.printStackTrace();
}
catch (TimeoutException e)
{
// timeout
e.printStackTrace();
if (fut != null)
{
// cancel the message
fut.cancel(true);
}
}
----

How to send a simple Binary message using the RemoteEndpoint, tracking the `Future<Void>` and waiting only prescribed amount of time for the send to complete, cancelling the message if the timeout occurs.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ The Connection State (is it open or not).

[source, java, subs="{sub-order}"]
----
if(session.isOpen()) {
if(session.isOpen())
{
// send message
}
----
Expand All @@ -34,7 +35,8 @@ Is the Connection Secure.

[source, java, subs="{sub-order}"]
----
if(session.isSecure()) {
if(session.isSecure())
{
// connection is using 'wss://'
}
----
Expand Down

0 comments on commit e0f3440

Please sign in to comment.