Skip to main content

You are looking at Signaling v1.x Docs. The newest version is  Signaling 2.x

Android
iOS
Web
macOS
Windows
Linux C++
Linux Java
Unity
Version: 1.x

SDK quickstart

This page shows you how to create your first Signaling using Signaling SDK.

Understand the tech

Log in to Signaling

The login process includes:

  1. The app client requests a token from your app server.

  2. The app server returns the token to the app client.

  3. The app client logs in to Signaling with the token.

Peer-to-peer messaging

The peer messaging process includes:

  1. Client A sends a peer message to Signaling.

  2. Signaling sends the message to client B. Client B receives the peer message.

Channel messaging

The channel messaging process includes:

  1. Client A creates a channel and join the channel.

  2. Client B and client C joins the channel created by client A.

  3. Client A sends a channel message to Signaling.

  4. Signaling sends the channel message to client B and C. Client B and client C receives the message.

For an app client to join a channel, you need the following information:

  • The App ID: A randomly generated string provided by Agora for identifying your app. You can get the App ID from Agora Console.

  • The user ID: The unique identifier of a user. You need to specify the user ID yourself, and ensure that it is unique in the channel.

  • A token: In a test or production environment, your app client retrieves tokens from your server.

  • The channel name: A string that identifies the channel for the channel messaging.

Prerequisites

In order to follow this procedure you must have:

  • An Agora account and project.

  • A computer with Internet access.

    Ensure that no firewall is blocking your network communication.

Create a Java project

Create a new folder RTM_quickstart with the following subfolders:

RTM_quickstart/
├── src
└── lib
Copy

Integrate Signaling SDK for Java

  1. Download the latest version of Signaling SDK and decompress the file. Copy the *.so file and the *.jar file to the lib folder.

  2. Create a file named pom.xml in RTM_quickstart with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>io.agora</groupId>
<artifactId><Vg k="MESS" />-Client-Demo</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>io.agora.rtm</groupId>
<artifactId>agora-rtm-sdk</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.0</version>
<executions>
<!-- Attach the shade into the package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>io.agora.mainClass.RtmJavaDemo</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

</plugins>
</build>
</project>
Copy

Implement Signaling

Create a RtmJavaDemo.java file in RTM_quickstart\src\main\java\io\agora and implement the file with the following steps:

  1. Import the following libraries.
package io.agora.mainClass;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import io.agora.rtm.RtmClient;
import io.agora.rtm.RtmClientListener;
import io.agora.rtm.RtmMessage;
import io.agora.rtm.RtmFileMessage;
import io.agora.rtm.RtmImageMessage;
import io.agora.rtm.RtmMediaOperationProgress;

import io.agora.rtm.ErrorInfo;
import io.agora.rtm.ResultCallback;
import io.agora.rtm.RtmChannel;
import io.agora.rtm.RtmChannelListener;
import io.agora.rtm.RtmChannelMember;
import io.agora.rtm.RtmStatusCode;
import io.agora.rtm.RtmChannelAttribute;
Copy
  1. Configure your App ID and token.
class Auth {
public static final String APP_ID = "<Your App ID>";
public static final String Token = "<Your token>";
}
Copy
  1. Implement the RtmChannelListener interface and override the following callbacks:
  • onMessageReceived: Occurs when the user receives a channel message. This callback returns sender uid and message instance.
  • onMemberJoined: Occurs when a member joins the channel. This callback returns the member uid.
  • onMemberLeft: Occurs when a member left the channel. This callback returns the member uid.
class ChannelListener implements RtmChannelListener {
private String channel_;

public ChannelListener(String channel) {
channel_ = channel;
}

@Override
public void onMemberCountUpdated(int memberCount) {
}

@Override
public void onAttributesUpdated(List<RtmChannelAttribute> attribute) {
}
// Occurs when the user receives a channel message. This callback returns sender uid and message instance.
@Override
public void onMessageReceived(
final RtmMessage message, final RtmChannelMember fromMember) {
String account = fromMember.getUserId();
String msg = message.getText();
System.out.println("Receive message from channel: " + channel_ +
" member: " + account + " message: " + msg);
}
// Occurs when a member joins the channel. This callback returns the member uid.
@Override
public void onMemberJoined(RtmChannelMember member) {
String account = member.getUserId();
System.out.println("member " + account + " joined the channel "
+ channel_);
}
// Occurs when a member left the channel. This callback returns the member uid.
@Override
public void onMemberLeft(RtmChannelMember member) {
String account = member.getUserId();
System.out.println("member " + account + " left the channel "
+ channel_);
}

@Override
public void onImageMessageReceived(RtmImageMessage message, RtmChannelMember fromMember){

}

@Override
public void onFileMessageReceived(RtmFileMessage message, RtmChannelMember fromMember){

}
}
Copy
  1. Implement the app class RtmJavaDemo with the following logic:

    • Initialize the client instance
    • Override the following callbacks:
    • onConnectionStateChanged: Occurs when the connection state changes and returns the new state with reason
    • onMessageReceived: Occurs when receiving a peer-to-peer message and returns a message instance and the sender uid
    • Log in to the Signaling
    • Log out of the Signaling
    • Send a peer-to-peer message
    • Send a channel message
    • Get channel member list
    public class RtmJavaDemo {
    private RtmClient mRtmClient;
    private RtmChannel mRtmChannel;
    private boolean loginStatus = false;
    private Scanner scn;

    public void init() {
    try {
    // Initialize the client instance
    mRtmClient = RtmClient.createInstance(Auth.APP_ID,
    new RtmClientListener() {
    // Occurs when the connection state changes and returns the new state with reason
    @Override
    public void onConnectionStateChanged(int state, int reason) {
    System.out.println("on connection state changed to "
    + state + " reason: " + reason);
    }

    // Occurs when receiving a peer-to-peer message and returns a message instance and the sender uid
    @Override
    public void onMessageReceived(RtmMessage rtmMessage, String peerId) {
    String msg = rtmMessage.getText();
    System.out.println("Receive message: " + msg
    + " from " + peerId);
    }

    @Override
    public void onTokenExpired() {
    }

    @Override
    public void onPeersOnlineStatusChanged(Map<String, Integer> peersStatus) {
    }

    @Override
    public void onImageMessageReceivedFromPeer(RtmImageMessage message, String peerId){

    }

    @Override
    public void onFileMessageReceivedFromPeer(RtmFileMessage message, String peerId){

    }

    @Override
    public void onMediaUploadingProgress(RtmMediaOperationProgress progress, long requestId){

    }

    @Override
    public void onMediaDownloadingProgress(RtmMediaOperationProgress progress, long requestId){

    }
    });
    } catch (Exception e) {
    System.out.println("Rtm sdk init fatal error!");
    throw new RuntimeException("Need to check rtm sdk init process");
    }
    scn = new Scanner(System.in);
    }

    public boolean login() {
    System.out.println("Please enter userID (literal \"null\" or starting " +
    "with space is not allowed, no more than 64 characters!):");
    String userId = scn.nextLine();
    if (userId.equals("") ||
    userId.startsWith(" ") ||
    userId.equals("null")) {
    System.out.println("Invalid userID detected!");
    return false;
    }
    // Log in to Signaling
    mRtmClient.login(Auth.Token, userId, new ResultCallback<Void>() {
    //@Override
    public void onSuccess(Void responseInfo) {
    loginStatus = true;
    System.out.println("login success!");
    }
    //@Override
    public void onFailure(ErrorInfo errorInfo) {
    loginStatus = false;
    System.out.println("login failure!");
    }
    });
    return true;
    }
    // Log out of Signaling
    public void logout() {
    loginStatus = false;
    mRtmClient.logout(null);
    }
    // CLI interface to send a peer-to-peer message
    public void p2pChat(String dst) {
    String msg;
    while(true) {
    System.out.println("please input message you want to send,"+
    " or input \'quit\' " + " to leave p2pChat");
    msg = scn.nextLine();
    if (msg.equals("quit")) {
    return;
    } else {
    sendPeerMessage(dst, msg);
    }
    }
    }
    // CLI interface to send a channel message
    public void groupChat(String channel) {
    String msg;
    mRtmChannel = mRtmClient.createChannel(channel,
    new ChannelListener(channel));
    if (mRtmChannel == null) {
    System.out.println("channel created failed!");
    return;
    }
    mRtmChannel.join(new ResultCallback<Void>() {
    @Override
    public void onSuccess(Void responseInfo) {
    System.out.println("join channel success!");
    }

    @Override
    public void onFailure(ErrorInfo errorInfo) {
    System.out.println("join channel failure! errorCode = "
    + errorInfo.getErrorCode());
    }
    });
    while(true) {
    System.out.println("please input message you want to send,"+
    " or input \'quit\' " + " to leave groupChat, " +
    "or input \'members\' to list members");
    msg = scn.nextLine();
    if (msg.equals("quit")) {
    mRtmChannel.leave(null);
    mRtmChannel.release();
    mRtmChannel = null;
    return;
    } else if (msg.equals("members")) {
    getChannelMemberList();
    } else {
    sendChannelMessage(msg);
    }
    }
    }
    // Send peer-to-peer message
    public void sendPeerMessage(String dst, String message) {
    RtmMessage msg = mRtmClient.createMessage();
    msg.setText(message);

    mRtmClient.sendMessageToPeer(dst, msg, new ResultCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
    }

    @Override
    public void onFailure(ErrorInfo errorInfo) {
    final int errorCode = errorInfo.getErrorCode();
    System.out.println("Send Message to peer failed, errorCode = "
    + errorCode);
    }
    });
    }
    // Get member list of a channel
    public void getChannelMemberList() {
    mRtmChannel.getMembers(new ResultCallback<List<RtmChannelMember>>() {
    @Override
    public void onSuccess(final List<RtmChannelMember> responseInfo) {
    for (int i = 0; i < responseInfo.size(); i++) {
    System.out.println("memberlist[" + i + "]" + ": "
    + responseInfo.get(i).getUserId());
    }
    }

    @Override
    public void onFailure(ErrorInfo errorInfo) {
    System.out.println("failed to get channel members, errCode = "
    + errorInfo.getErrorCode());
    }
    });
    }
    // Send channel message
    public void sendChannelMessage(String msg) {
    RtmMessage message = mRtmClient.createMessage();
    message.setText(msg);

    mRtmChannel.sendMessage(message, new ResultCallback<Void>() {
    @Override
    public void onSuccess(Void aVoid) {
    }

    @Override
    public void onFailure(ErrorInfo errorInfo) {
    final int errorCode = errorInfo.getErrorCode();
    System.out.println("Send Message to channel failed, erroCode = "
    + errorCode);
    }
    });
    }
    // Implement the main CLI logic
    public static void main(String[] args) {
    RtmJavaDemo client_ = new RtmJavaDemo();
    client_.init();
    while(true) {
    if (!client_.loginStatus) {
    if (!client_.login())
    continue;
    }
    System.out.println("1: peer to peer chat\n"
    + "2: group chat\n"
    + "3: logout");
    System.out.println("please input your choice:");
    Scanner scn = new Scanner(System.in);
    int choice;
    if (scn.hasNextInt()) {
    choice = scn.nextInt();
    } else {
    System.out.println("your input is not an int type");
    continue;
    }
    if (choice == 1) {
    System.out.println("please input your destination user ID:");
    scn.nextLine();
    String dst = scn.nextLine();
    System.out.println("input destination ID:" + dst);
    client_.p2pChat(dst);
    } else if (choice == 2) {
    System.out.println("please input your channel ID:");
    scn.nextLine();
    String channel = scn.nextLine();
    client_.groupChat(channel);
    } else if (choice == 3) {
    client_.logout();
    System.out.println("quit the demo? yes/no");
    scn.nextLine();
    if (scn.hasNextLine()) {
    String quit = scn.nextLine();
    if (quit.equals("yes")) {
    break;
    }
    }
    } else {
    continue;
    }
    }
    System.out.println("leaving demo...");
    System.exit(0);
    }
    }
    Copy

Test your Java app

Refer to the following steps to run the sample project:

  1. Install the .jar file to local maven.

    $ mvn install:install-file -Dfile=lib/agora_rtm.jar -DgroupId=io.agora.rtm -DartifactId=agora-rtm-sdk -Dversion=1.0 -Dpackaging=jar
    Copy
  2. Run mvn package in the folder of pom.xml.

    $ mvn package
    Copy
  3. Run the sample project.

    $ java -cp target/<Vg k="MESS" />-Client-Demo-1.0-SNAPSHOT.jar -Dsun.boot.library.path=lib/ io.agora.mainClass.RtmJavaDemo
    Copy

Considerations for Java

  • The Agora Signaling SDK supports creating multiple RtmClient instances that are independent of each other.

  • To send and receive peer-to-peer or channel messages, ensure that you have successfully logged in the Agora Signaling (you have received onSuccess.

  • To use any of the channel features, you must first call the createChannel method to create a channel instance.

  • You can create multiple channel instances for each RtmClient instance, but you can only join a maximum of 20 channels at the same time. The channelId parameter needs to be channel-specific.

  • When you leave a channel and do not want to join it again, you can call the release method to release all resources used by the channel instance.

  • You cannot reuse a received RtmMessage instance.

Next steps

Generating a token by hand is not helpful in a production context. Authenticate Your Users with Tokens shows you how to start live streaming with a token that you retrieve from your server.

Signaling