Skip to content

RPC development

jmarine edited this page Sep 25, 2014 · 37 revisions

This is the methodology to add new functions that can be called by WAMP clients:

  1. Create a new Java class that extends WampModule. The class must have a constructor with 1 parameter of the type WampApplication.

  2. The class must also use the @WampModuleName annotation to specify the base URI of the procedures/topics that will be defined by the module.

  3. To develop new RPCs, define the methods as public and use the @WampRPC annotation (it has an optional "name" parameter to change the Java method name for the WAMP clients). You can also override the "onCall" method to intercept the RPCs, and add new business logic.

Code example:

package org.acme.myapp;

import org.wgs.wamp.WampApplication;
import org.wgs.wamp.WampModule;
import org.wgs.wamp.WampSocket;
import org.wgs.wamp.annotation.WampModuleName;
import org.wgs.wamp.annotation.WampRPC;
import org.wgs.wamp.types.WampList;

@WampModuleName("myservice")
public class MyModule extends WampModule
{
    private WampApplication wampApp;

    public MyModule(WampApplication app) {
        super(app);
        this.wampApp = app;
    }

    @WampRPC(name="sum")
    public long sumArguments( /* WampSocket socket, */ WampList args) throws Exception {
        long sum = 0;
        for(int i = 0; i < args.size(); i++) {
           sum += args.getLong(i);
        }
        return sum;
    }

    // NOTE: the method is not public neighter annotated with "WampRPC",
    // but "onCall" method can intercept the RPC and invoke it.
    private long multiplyArguments( /* WampSocket socket, */ WampList args) throws Exception {
        long retval = args.getLong(0);
        for(int i = 1; i < args.size(); i++) {
           retval *= args.getLong(i);
        }
        return retval;
    }


    @Override
    public Object onCall(WampCallController task, WampSocket clientSocket, String methodName, WampList args, WampDict argsKw, WampCallOptions options) throws Exception {
        if(methodName.equals("myservice.multiply")) return multiplyArguments(args);
        else return super.onCall(task, clientSocket, methodName, args, argsKw, options);  // to invoke the methods annotated with "WampRPC"
    }

}
  1. Finally, attach the modules to the WAMP application context (uri).

4.1) Deployment with the standalone server: specify the canonical name of the classes in the "context.yourContextName.modules" property of the "wgs.properties" configuration file (separated by ',')

Example:

docroot=../wwwroot

contexts=app1
context.app1.uri=/myuri
context.app1.modules=org.acme.myapp.MyModule
context.app1.topics=myservice.topic1,myservice.topic2

4.2) Deployment with a JavaEE application server:

To use websockets, create a class derived from WampEndpoint and override onApplicationStart method, to register the module instances and create the application topics. Then, create another class derived from ServerApplicationConfig to configure the URL and your endpoint class.

Example:

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;

import org.wgs.wamp.WampApplication;
import org.wgs.wamp.transport.http.websocket.WampEndpoint;
import org.wgs.wamp.transport.http.websocket.WampEndpointConfig;


public class MyApplicationConfig implements ServerApplicationConfig 
{
  @Override
  public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> set) {
    return new HashSet<ServerEndpointConfig>() {
      {
        add(new WampEndpointConfig(MyEndpoint.class, new WampApplication(WampApplication.WAMPv2, "/myuri")));
      }
    };
  }

  @Override
  public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> set) {
    return Collections.emptySet();
  }
  

  public static class MyEndpoint extends WampEndpoint
  {
        @Override
        public void onApplicationStart(WampApplication app) { 
            super.onApplicationStart(app);
            app.registerWampModule(new org.acme.myapp.MyModule()); 
            WampBroker.createTopic(app, "myservice.topic1", null);
            WampBroker.createTopic(app, "myservice.topic2", null);
        }
    }

}
    

If you want HTTP long-polling support, create a class derived from WampLongPollingServlet and override onApplicationStart method, to register the module instances and create the application topics:

Example:

import org.wgs.wamp.WampApplication;
import org.wgs.wamp.transport.http.longpolling.WampLongPollingServlet;

@WebServlet(urlPatterns = "/myuri-longpoll", asyncSupported = true)
public class MyLongPollingServlet extends WampLongPollingServlet
{
    @Override
    public void onApplicationStart(WampApplication app) 
    {
            app.registerWampModule(new org.acme.myapp.MyModule()); 
            WampBroker.createTopic(app, "myservice.topic1", null);
            WampBroker.createTopic(app, "myservice.topic2", null);
    }
    
}
Clone this wiki locally