SkillAgentSearch skills...

Jawampa

Web Application Messaging Protocol (WAMP v2) support for Java

Install / Use

/learn @Matthias247/Jawampa
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

THIS LIBRARY IS UNMAINTAINED

No updates for any bug, security issue or any dependency had been implemented for long time, and no further development for this library is planned.

jawampa

  • is a library that brings support for the Web Application Messaging Protocol [WAMP] to Java.
  • provides WAMPv2 client side functionality as well as server side functionality and supports all currently defined WAMPv2 roles (caller, callee, publisher, subscriber, broker, dealer).
  • provides a pluggable transport layer. Connection providers and servers which use different networking mechanisms and low-level libraries can be built and plugged into jawampa.
  • exposes the client-side user-interface through RxJava Observables, which enable powerful compositions of different asynchronous operations and provide an easy solution for delegating data handling between different threads.
    Observables are also used in places where only single return values are expected and Futures would be sufficient - However the common use of Observables provides less dependencies and allows to schedule continuations for all kinds of asynchronous operations in a consistent way.
  • is compatible with Java6. However the examples in this document use Java8 syntax for convenience.

Install

Declare the following dependency for the base library:

<dependency>
    <groupId>ws.wamp.jawampa</groupId>
    <artifactId>jawampa-core</artifactId>
    <version>0.5.0</version>
</dependency>

However as the core library of jawampa does not provide a transport layer users should typically use a jawampa transport provider library (e.g. jawampa-netty - see subdirectory) as a depency.
This will automatically also add a dependency on jawampa-core.

WAMP client API (WampClient)

The client-side API is exposed through the WampClient object.
WampClients must be created through WampClientBuilder objects, which allow to configure the created clients.

There are 3 mandatory parameters that have to be set through the builder:

  • A connector provider which describes the framework which will be used for establishing a connection to the WAMP router. An example is the NettyWampClientConnectorProvider which is described in the documentation of the jawampa-netty subproject.
  • The URI that describes the address of the WAMP router
  • The realm that the client should join on the router

Additionally there exist some optional parameters, which for example allow to activate automatic reconnects between the client and the router or allow to configure how the client should behave in case of communication errors.

Example:

final WampClient client;
try {
    // Create a builder and configure the client
    WampClientBuilder builder = new WampClientBuilder();
    builder.withConnectorProvider(connectorProvider)
           .withUri("ws://localhost:8080/wamprouter")
           .withRealm("examplerealm")
           .withInfiniteReconnects()
           .withReconnectInterval(5, TimeUnit.SECONDS);
    // Create a client through the builder. This will not immediatly start
    // a connection attempt
    client = builder.build();
} catch (WampError e) {
    // Catch exceptions that will be thrown in case of invalid configuration
    System.out.println(e);
    return;
}

The WampClient object provides the RxJava Observable statusChanged() that notifies the user about the current status of the session between the client and the router, which can be either DisconnectedState, ConnectingState or ConnectedState. The application can monitor this Observable to detect when other steps should be performed (e.g. subscribe to topics or register functions after connect).

The onNext() status notification method of the Subscriber will be called on the WampClients thread. However it can easily be delegated to a Scheduler or EventLoop of the host application be using the Observable.observerOn() member function.

statusChanged() returns a BehaviorObservable, therefore it will immediatly send a notification about the current state to subscribers on subscribe and not only in case of state changes.

Example:


client.statusChanged()
      .observeOn(applicationScheduler)
      .subscribe((WampClient.State newState) -> {
        if (newState instanceof WampClient.ConnectedState) {
          // Client got connected to the remote router
          // and the session was established
        } else if (newState instanceof WampClient.DisconnectedState) {
          // Client got disconnected from the remoute router
          // or the last possible connect attempt failed
        } else if (newState instanceof WampClient.ConnectingState) {
          // Client starts connecting to the remote router
        }});

In order to start the connection between a client and a router the clients open() member function has to be called. This will lead to the first connection attempt and a state change from DisconnectedState to ConnectingState.

When the client is no longer needed is must be closed with the close() member function. This will shutdown the connection to the remote router and stop all reconnect attempts. After a WampClient was closed it can not be reopened again. Instead of this a new instance of the WampClient should be created if necessary.

The close process is also asynchronous. Therefore a call to close() does not guarantee an immediate close of the client. However the close() call returns an Observable which can be used to wait until the client was successfully closed.

Example for a typical session lifecycle:

WampClient client = builder.build();
client.statusChanged().subscribe(...);
client.open();

// ...
// use the client here
// ...

// Wait synchronously for the client to close
// On environments like UI thread asynchronous waiting should be preferred
client.close().toBlocking().last();

Performing procedure calls

Remote procedure calls can be performed through the various call member functions of the WampClient.

All overloaded version of call require the name of the procedure that should be called (and which must be a valid WAMP Uri) as the first parameter. All versions of call() return an Observable which is used to transfer the result of the function call in an asynchronous fashion to the caller. It is a hot observable, which means the call will be made indepently of whether someone subscribes to it or not. However the result will be cached in the Observable, which means that also late subscribers will be able to retrieve the result.

  • If the procedure call succeeds the subscribers onNext method will be called with the result and followed by an onCompleted call.
  • If the remote procedure call fails then the subscribers onError() method will be called with the occurred error as a parameter.

The different overloads of call() allow to provide the arguments to the procedure in different fashions as well as to retrieve the return value in a different fashion:

The most explicit signature of call is
Observable<Reply> call(String procedure, ArrayNode arguments, ObjectNode argumentsKw)
It allows to pass positional arguments as well as keyword arguments to the WAMP procedure and will return a structure which will as well contains fields for the positional and keyword arguments of the call result.
The arguments and return values use the ArrayNode and ObjectNode data types from the Jackson JSON library which describe an array or object of arbitrary other types.

If only positional arguments are required for the call the simplified variant
Observable<Reply> call(String procedure, Object... args)
can be used which allows to pass the positional arguments as a varargs array. It will also automatically use Jacksons object mapping capabilities to convert all Java POJO keyword arguments in their JsonNode form and create an argument array from that. This means you can directly use any kind of Java objects as function parameters as long as they can be properly serialized and deserialized by Jackson. For more complex data structures you might need to use annotations to instruct the serializer.

The last variant of call() provides some further convenience and has the following signature: <T> Observable<T> call(String procedure, Class<T> returnValueClass, Object... args).
It can be used when the procedure provides none or a single positional return value. Then you can specify the type of the expected return value in the second arguments and call will automatically try to map the first result argument of the procedure call into the required type. This will also be done through Jackson object mapping.

With this simplification you can call remote procedures and listen for return values in the following way (with Java8):

Observable<String> result = client.call("myservice.concat", String.class, "Hello nr ", 123);
// Subscribe for the result
// onNext will be called in case of success with a String value
// onError will be called in case of errors with a Throwable
result.observeOn(applicationScheduler)
      .subscribe((txt) -> System.out.println(txt),
                 (err) -> System.err.println(err));

Providing remote procedures to other clients

With WAMP all clients that are connected to a router are able to provide procedures that can be used by any other client.

jawampa exposes this functionality though the registerProcedure() member function. registerProcedure will return an Observable which will be used to receive incoming function calls. Each incoming request to the registered procedure name will be pushed to the Subscribers onNext method in form of a Request class. The application can retrieve and process requests on any thread through observeOn

View on GitHub
GitHub Stars151
CategoryCustomer
Updated14d ago
Forks59

Languages

Java

Security Score

95/100

Audited on Mar 24, 2026

No findings