All Projects → crossbario → Autobahn Java

crossbario / Autobahn Java

Licence: mit
WebSocket & WAMP in Java for Android and Java 8

Programming Languages

java
68154 projects - #9 most used programming language
python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Autobahn Java

Autobahn Python
WebSocket and WAMP in Python for Twisted and asyncio
Stars: ✭ 2,305 (+57.12%)
Mutual labels:  rpc, wamp, pubsub, websocket, real-time, autobahn
Autobahn Js
WAMP in JavaScript for Browsers and NodeJS
Stars: ✭ 1,345 (-8.32%)
Mutual labels:  rpc, wamp, pubsub, websocket, real-time
Wampsharp
A C# implementation of WAMP (The Web Application Messaging Protocol)
Stars: ✭ 355 (-75.8%)
Mutual labels:  rpc, wamp, pubsub, websocket, real-time
Wampy
Websocket RPC and Pub/Sub for Python applications and microservices
Stars: ✭ 115 (-92.16%)
Mutual labels:  rpc, wamp, pubsub, websocket
Autobahn Cpp
WAMP for C++ in Boost/Asio
Stars: ✭ 231 (-84.25%)
Mutual labels:  rpc, wamp, pubsub, real-time
Deepstream.io
deepstream.io server
Stars: ✭ 6,947 (+373.55%)
Mutual labels:  rpc, pubsub, websocket
Centrifuge
Real-time messaging library for Go with scalability in mind
Stars: ✭ 446 (-69.6%)
Mutual labels:  pubsub, websocket, real-time
Centrifugo
Scalable real-time messaging server in a language-agnostic way. Set up once and forever.
Stars: ✭ 5,649 (+285.07%)
Mutual labels:  websocket, real-time, pubsub
Poxa
Pusher server implementation compatible with Pusher client libraries.
Stars: ✭ 898 (-38.79%)
Mutual labels:  pubsub, websocket
Libzmq
ZeroMQ core engine in C++, implements ZMTP/3.1
Stars: ✭ 7,418 (+405.66%)
Mutual labels:  pubsub, network
Sockjs Client
WebSocket emulation - Javascript client
Stars: ✭ 7,808 (+432.24%)
Mutual labels:  websocket, real-time
Ws Promise Client
PROJECT MOVED: https://github.com/kdex/ws-promise
Stars: ✭ 6 (-99.59%)
Mutual labels:  rpc, websocket
Beaver
💨 A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
Stars: ✭ 1,056 (-28.02%)
Mutual labels:  pubsub, websocket
Loowy
Lua WAMP client
Stars: ✭ 28 (-98.09%)
Mutual labels:  wamp, pubsub
Hemera
🔬 Writing reliable & fault-tolerant microservices in Node.js https://hemerajs.github.io/hemera/
Stars: ✭ 773 (-47.31%)
Mutual labels:  rpc, pubsub
Wheel
关于net nio os cache db rpc json web http udp tcp mq 等多个小工具的自定义实现
Stars: ✭ 45 (-96.93%)
Mutual labels:  rpc, network
Engine.io Client
Stars: ✭ 649 (-55.76%)
Mutual labels:  websocket, real-time
Rtb
Benchmarking tool to stress real-time protocols
Stars: ✭ 35 (-97.61%)
Mutual labels:  websocket, real-time
Kubemq
KubeMQ is Enterprise-grade message broker native for Docker and Kubernetes
Stars: ✭ 58 (-96.05%)
Mutual labels:  rpc, pubsub
Chat Engine
Object oriented event emitter based framework for building chat applications in Javascript.
Stars: ✭ 87 (-94.07%)
Mutual labels:  pubsub, websocket

Autobahn|Java

Client library providing WAMP on Java 8 (Netty) and Android, plus (secure) WebSocket for Android.

Docker Hub Travis Docs


Autobahn|Java is a subproject of the Autobahn project and provides open-source client implementations for

running on Android and Netty/Java8/JVM.

The WebSocket layer is using a callback based user API, and is specifically written for Android. Eg it does not run any network stuff on the main (UI) thread.

The WAMP layer is using Java 8 CompletableFuture for WAMP actions (call, register, publish and subscribe) and the Observer pattern for WAMP session, subscription and registration lifecycle events.

The library is MIT licensed, maintained by the Crossbar.io Project, tested using the AutobahnTestsuite and published as a JAR to Maven and as a Docker toolchain image to Dockerhub.


Download

Grab via Maven:

<dependency>
    <groupId>io.crossbar.autobahn</groupId>
    <artifactId>autobahn-android</artifactId>
    <version>21.7.1</version>
</dependency>

Gradle:

dependencies {
    implementation 'io.crossbar.autobahn:autobahn-android:21.7.1'
}

For non-android systems use artifactID autobahn-java or just Download the latest JAR

Getting Started

The demo clients are easy to run, you only need make and docker installed to get things rolling.

$ make crossbar # Starts crossbar in a docker container
$ make python # Starts a python based WAMP components that provides calls for the Java demo client

and finally

$ make java # Starts the java (Netty) based demo client that performs WAMP actions

Show me some code

The code in demo-gallery contains some examples on how to use the autobahn library, it also contains convenience methods to use. Below is a basic set of code examples showing all 4 WAMP actions.

Subscribe to a topic

public void demonstrateSubscribe(Session session, SessionDetails details) {
    // Subscribe to topic to receive its events.
    CompletableFuture<Subscription> subFuture = session.subscribe("com.myapp.hello",
            this::onEvent);
    subFuture.whenComplete((subscription, throwable) -> {
        if (throwable == null) {
            // We have successfully subscribed.
            System.out.println("Subscribed to topic " + subscription.topic);
        } else {
            // Something went bad.
            throwable.printStackTrace();
        }
    });
}

private void onEvent(List<Object> args, Map<String, Object> kwargs, EventDetails details) {
    System.out.println(String.format("Got event: %s", args.get(0)));
}

Since we are only accessing args in onEvent(), we could simplify it like:

private void onEvent(List<Object> args) {
    System.out.println(String.format("Got event: %s", args.get(0)));
}

Publish to a topic

public void demonstratePublish(Session session, SessionDetails details) {
    // Publish to a topic that takes a single arguments
    List<Object> args = Arrays.asList("Hello World!", 900, "UNIQUE");
    CompletableFuture<Publication> pubFuture = session.publish("com.myapp.hello", args);
    pubFuture.thenAccept(publication -> System.out.println("Published successfully"));
    // Shows we can separate out exception handling
    pubFuture.exceptionally(throwable -> {
        throwable.printStackTrace();
        return null;
    });
}

A simpler call would look like:

public void demonstratePublish(Session session, SessionDetails details) {
    CompletableFuture<Publication> pubFuture = session.publish("com.myapp.hello", "Hi!");
    ...
}

Register a procedure

public void demonstrateRegister(Session session, SessionDetails details) {
    // Register a procedure.
    CompletableFuture<Registration> regFuture = session.register("com.myapp.add2", this::add2);
    regFuture.thenAccept(registration ->
            System.out.println("Successfully registered procedure: " + registration.procedure));
}

private CompletableFuture<InvocationResult> add2(
        List<Object> args, Map<String, Object> kwargs, InvocationDetails details) {
    int res = (int) args.get(0) + (int) args.get(1);
    List<Object> arr = new ArrayList<>();
    arr.add(res);
    return CompletableFuture.completedFuture(new InvocationResult(arr));
}

A very precise add2 may look like:

private List<Object> add2(List<Integer> args, InvocationDetails details) {
    int res = args.get(0) + args.get(1);
    return Arrays.asList(res, details.session.getID(), "Java");
}

Call a procedure

public void demonstrateCall(Session session, SessionDetails details) {
    // Call a remote procedure.
    CompletableFuture<CallResult> callFuture = session.call("com.myapp.add2", 10, 20);
    callFuture.thenAccept(callResult ->
            System.out.println(String.format("Call result: %s", callResult.results.get(0))));
}

Calling procedure with variable data type parameters

public void demonstrateCall(Session session, SessionDetails details) {
    // Call a remote procedure.
    byte[] var1 = new byte[20];
    String var2 = "A sample text";
    int var3 = 99;
    List<Object> args = new ArrayList<>();
    args.add(var1);
    args.add(var2);
    args.add(var3);
    CompletableFuture<CallResult> callFuture = session.call("com.myapp.myproc", args);
    callFuture.thenAccept(callResult ->
            System.out.println(String.format("Call result: %s", callResult.results.get(0))));
}

Connecting the dots

public void main() {
    // Create a session object
    Session session = new Session();
    // Add all onJoin listeners
    session.addOnJoinListener(this::demonstrateSubscribe);
    session.addOnJoinListener(this::demonstratePublish);
    session.addOnJoinListener(this::demonstrateCall);
    session.addOnJoinListener(this::demonstrateRegister);

    // finally, provide everything to a Client and connect
    Client client = new Client(session, url, realm);
    CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}

Authentication

Authentication is simple, we just need to create an object of the desired authenticator and pass that to the Client

Ticket Auth

public void main() {
    ...
    IAuthenticator authenticator = new TicketAuth(authid, ticket);
    Client client = new Client(session, url, realm, authenticator);
    CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}

Challenge Response Auth

public void main() {
    ...
    IAuthenticator authenticator = new ChallengeResponseAuth(authid, secret);
    Client client = new Client(session, url, realm, authenticator);
    CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}

Cryptosign Auth

public void main() {
    ...
    IAuthenticator authenticator = new CryptosignAuth(authid, privkey, pubkey);
    Client client = new Client(session, url, realm, authenticator);
    CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}

You can also provide a list of Authenticators

public void main() {
    ...
    List<IAuthenticator> authenticators = new ArrayList<>();
    authenticators.add(new TicketAuth(authid, ticket));
    authenticators.add(new CryptosignAuth(authid, privkey, pubkey));
    Client client = new Client(session, url, realm, authenticators);
    CompletableFuture<ExitInfo> exitInfoCompletableFuture = client.connect();
}

Autobahn also supports POJOs

Here is how to call a remote procedure that returns a list of Person POJOs

// Call a remote procedure that returns a Person with id 1
CompletableFuture<Person> callFuture = mSession.call("com.example.get_person", 1);
callFuture.whenCompleteAsync((person, throwable) -> {
    if (throwable != null) {
        // handle error
    } else {
        // success!
        // do something with person
    }
}, mExecutor);
// call a remote procedure that returns a List<Person>
CompletableFuture<List<Person>> callFuture = mSession.call(
        // remote procedure to call
        "com.example.get_persons_by_department",

        // positional call arguments
        new ArrayList<Object>() {List.of("department-7")},

        // call return type
        new TypeReference<List<Person>>() {}
);

callFuture.whenCompleteAsync((persons, throwable) -> {
    if (throwable != null) {
        // handle error
    } else {
        // success!
        for (Person person: persons) {
            // do something with person
        }
    }
}, mExecutor);

Also register a procedure that returns a Person

private Person get_person() {
    return new Person("john", "doe", "hr");
}

private void main() {
    CompletableFuture<Registration> regFuture = session.register(
            "io.crossbar.example.get_person", this::get_person);
    regFuture.whenComplete((registration, throwable) -> {
        System.out.println(String.format(
                "Registered procedure %s", registration.procedure));
    });
}

WebSocket on Android

Echo example

WebSocketConnection connection = new WebSocketConnection();
connection.connect("wss://echo.websocket.org", new WebSocketConnectionHandler() {
    @Override
    public void onConnect(ConnectionResponse response) {
        System.out.println("Connected to server");
    }

    @Override
    public void onOpen() {
        connection.sendMessage("Echo with Autobahn");
    }

    @Override
    public void onClose(int code, String reason) {
        System.out.println("Connection closed");
    }

    @Override
    public void onMessage(String payload) {
        System.out.println("Received message: " + payload);
        connection.sendMessage(payload);
    }
});

Building from source

Building Autobahn is pretty simple

Android build

For Android, we recommend to use Android Studio. Just import the project in Android Studio, it will tell you if there are any missing dependencies, install them and then just build the project from Build > Rebuild Project and you will have the aar artifact in autobahn/build/outputs/aar/

Netty build

To produce a build for non-android systems make sure you have docker and make installed then just use run below command on the root directory of the project

make build_autobahn

and that will output the jar file in autobahn/build/libs/.

Get in touch

Get in touch by joining our forum.


Version 1

Version 1 of this library is still in the repo here, but is no longer maintained.

Version 1 only supported non-secure WebSocket on Android and only supported WAMP v1.

Both of these issues are fixed in the (current) version of Autobahn|Java.


Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].