Table of Contents
List of Examples
JUV RTMP Tester is a lightweight library/tool that lets you execute functional/regression/load testing of the RTMP server side functionality.
Related:
JUV RTMP Client - J2SE RTMP client
JUV RTMP Client (J2ME edition) - J2ME RTMP client
JUV RTMP Researcher - RTMP debug tool
JUV RTMP Tester library consists of the only JAR file (no dependencies) that should be placed in the class path.
Library requires a license key. If it is not set or invalid then it operates in evaluation (lite) mode.
Evaluation version has next limitations:
There are 2 core entities (classes) provided by the library.
Every method invoked by the server is processed by the IMethodInvoker instance. The default implementation (com.smaxe.uv.invoker.support.MethodInvoker) is based on reflection.
public interface IMethodInvoker { /** * Invokesmethod
with theargs
of the objecto
. * The result is returned through the {@link ICallback callback}. * * @param o object which method is invoked * @param method method to invoke * @param callback callback to receive invocation result * @param args method arguments */ public void invoke(final Object o, final String method, final ICallback callback, final Object... args); }
Every custom Java object that is sent/received to/from the server must be presented as ClassObject, i.e. class name + {property : property value} map. The IObjectCreator implementation is responsible for the such transformation.
public interface IObjectCreator { /** * Converts {@link ClassObject co} to the custom type object. * * @param coClassObject
instance * @return custom object */ public Object toObject(final ClassObject co); /** * Converts {@link Object o} to the {@link ClassObject} instance. * * @param o object to represent asClassObject
* @returnClassObject
instance */ public ClassObject toClassObject(final Object o); }
The library doesn't use any specific logging system. It provides a simple interface that lets you either integrate the library with any logging library or use ILogger implementations provided in the com.smaxe.logger.support package.
public interface ILogger
{
/**
* Logs the message.
*
* @param level message level
* @param message message to log
* @param t thrown exception, null
if the exception is not thrown
* @param args optional arguments
*/
public void log(final int level, final String message, final Throwable t, final Object... args);
}
Example 4.1. Set license key
com.smaxe.app.uv.loadtester.RtmpTester.setKey("00000-00000-00000-00000-00000");
Example 4.2. Simplest script (just connects to the server)
/** * SimpleScript * Behaviour: * - Client just connects to the server. */ public final class SimpleScript extends RtmpClientScript { /** * Constructor. */ public SimpleScript() { } }
Example 4.3. Script that connects to the server using connection parameters
/** * SimpleScript2 * Behaviour: * - Client connects to the server using connection parameters. */ public final class SimpleScript2 extends RtmpClientScript { /** * Constructor. */ public SimpleScript2() { } @Override public Object[] onStart() { return new Object[] {"username", "password", "age"} } }
Example 4.4. Script that plays stream and disconnects on playback stop
/** * PlayStreamScript * Behaviour: * - Client connects to the server and starts stream playback on successfull connection * (stream name is defined in the "streamToPlay" property) * - Client disconnects from the server after stream playback is stopped/completed. */ public final class PlayStreamScript extends RtmpClientScript { /** * Constructor. */ public PlayStreamScript() { } @Override public void onConnect(final String code, final Map info) { super.onConnect(code, info); play((String) properties().get("streamToPlay")); } @Override public void onPlayStop(final String stream, final MediaStreamInfo info) { super.onPlayStop(stream, info); disconnect(); } }
Example 4.5. Script that publishes stream and disconnects on publish stop
/** * PublishStreamScript * Behaviour: * - Client connects to the server and publishes stream on successfull connection * (stream name is defined in the "streamToPublish" property, stream source is a local flv file). * - Client disconnects from the server after stream publish is stopped/completed. */ public final class PublishStreamScript extends RtmpClientScript { /** * Constructor. */ public PublishStreamScript() { } @Override public void onConnect(final String code, final Map info) { super.onConnect(code, info); publish((String) properties().get("streamToPublish") + "_" + getClientId(), -1, PUBLISH_MODE_LIVE); } @Override public void onPublishStop(final String stream) { super.onPublishStop(stream); disconnect(); } }
Example 4.6. Script that connects to the remote shared object
/** * ConnectSharedObjectScript * Behaviour: * - Client connects to the server and connects to shared object "test" * - Client sets "attribute" value to 1 on shared object connection. * - Client increments "attribute" value by 1 on every "attribute" value update and * disconnects if value exceeds 15. */ public final class ConnectSharedObjectScript extends RtmpClientScript { /** * Constructor. */ public ConnectSharedObjectScript() { } @Override public void onConnect(final String code, final Map info) { super.onConnect(code, info); connectSharedObject("test"); } @Override public void onSharedObjectConnect(final String name) { super.onSharedObjectConnect(name); getSharedObjectData(name).put("attribute", 1 /*value*/); } @Override public void onSharedObjectChange(final String name, final String attribute, final Object oldValue, final Object newValue) { super.onSharedObjectChange(name, attribute, oldValue, newValue); if ("test".equals(name)) { if ("attribute".equals(attribute)) { getSharedObjectData(name).put(attribute, ((Integer) newValue).intValue() + 1); if ((Integer) getSharedObjectData(name).get(attribute) > 15) { closeSharedObject(name); disconnect(); } else if ((Integer) getSharedObjectData(name).get(attribute) > 10) { sendSharedObjectAction(name, "notifyEveryone", new Object[] {"Attribute value exceeded 10!"}); } } } } @Override public void onSharedObjectDisconnect(final String name) { super.onSharedObjectDisconnect(name); } }
Example 4.7. RtmpTester executes ConnectSharedObjectScript script
RtmpTester tester = new RtmpTester(); // note: set license key before tester.emulateClient(*) invocation tester.emulateClient("rtmp://localhost/live", new RtmpClientInfo(ConnectSharedObjectScript.class.getCanonicalName), null /*callback*/);
Example 4.8. Get bandwidth used by script as a function of time
public final class RtmpTesterCallback extends Object implements RtmpTester.ICallback { /** * Constructor. */ public RtmpTesterCallback() { } /** * Notifies about disconnection from the server. * You can use {@link RtmpTester.IClientSessionInfoProvider provider} * to get session details. */ public void onDisconnect(final RtmpTester.IClientSessionInfoProvider provider) { System.out.println("RtmpTesterCallback#onDisconnect: " + provider.id()); // NOTE: // RtmpTester can provide you with Bandwidth as a function of time System.out.println("Bandwidth(t):"); for (Map entry : provider.getEntities(RtmpTester.IClientSessionInfoProvider.BANDWIDTH, null /*selector*/)) { // bandwidth entry represents a map (field name -> value) // for example, // {stimestamp=1297, readBytes=87237, writtenBytes=3420, readPackets=221, writtenPackets=5} // where stimestamp is session timestamp System.out.println(entry); } } }