Skip to main content

Quick Integration of Live Chatroom

This tutorial describes how to quickly implement a live chatroom on the Android platform (Java) using RC's IM SDK.

Prerequisites

Create a RC developer account and obtain the [App Key].

Step 1: Import the SDK

Using Gradle in Android Studio, you can add RC's Instant Messaging library (IMLib) as a remote dependency or a local Android library module to your build.

This tutorial demonstrates adding a remote dependency via Gradle. Note that the RC Maven repository is used.

  1. Open the build.gradle file in the root directory (under the Project view) and declare RC's Maven repository.

    allprojects {
    repositories {
    ...
    // RC Maven repository URL
    maven {url "https://maven.rongcloud.cn/repository/maven-releases/"}
    }
    }
  2. In the app's build.gradle, add RC's Instant Messaging library (IMLib) as a remote dependency.

    dependencies {
    ...
    api 'cn.rongcloud.sdk:im_libcore:5.4.1'
    api 'cn.rongcloud.sdk:im_chatroom:5.4.1'
    }

Step 2: Initialize the SDK

Initialize the SDK in the onCreate() method of the Application class by passing the App Key and initialization configuration (InitOption). If the App Key does not belong to the China (Beijing) Data Center, you must specify the navigation server and statistics server addresses in the initialization configuration.

String appKey = "Your_AppKey";

InitOption initOption = new InitOption.Builder()
.setNaviServer("http(s)://naviServer") // If the App Key belongs to the Singapore or North America Data Center, configure the corresponding navigation server address
.setStatisticServer("http(s)://StatisticServer") // If the App Key belongs to the Singapore or North America Data Center, configure the corresponding statistics server address
.build();

RongCoreClient.init(context, appKey, initOption);
  • Singapore Data Center Navi Server Address: nav.sg-light-edge.com (primary), nav-b.sg-light-edge.com (backup)
  • Singapore Data Center StatisticServer Address: stats.sg-light-edge.com

Step 3: Add Message Listener

The app needs to receive messages and notifications through the message listener provided by the SDK. The current user will receive all types of messages through this listener. It is recommended to register the message listener during the app's lifecycle.

RongCoreClient.addOnReceiveMessageListener(
new OnReceiveMessageWrapperListener() {
@Override
public boolean onReceivedMessage(Message message, int left, boolean hasPackage, boolean offline) {
///
return false;
}
});

Step 4: Establish IM Connection

Before using RC's Instant Messaging features, an IM connection must be established with the RC server. A user Token is required to establish the IM connection.

The user Token passed when establishing the IM connection represents the user's unique identifier in RC. You need to maintain the app's user registration process, assign a unique user identifier (User ID) to the user, and use this User ID to request a Token from RC for establishing the IM connection.

Step 4.1: Obtain Token

The client SDK does not provide an API for obtaining a Token. You need to obtain the Token through RC's server-side API.

Exchange the user ID (userId) defined at the app layer for an authentication Token used in RC services. The same user ID can be used to obtain a Token multiple times. If the Token is still valid, it can be used to connect to RC services. To obtain a new Token for the same user ID, use the same interface.

Authentication is required when calling RC's server-side API. Add the following HTTP header fields to the request:

  • App-Key: App Key
  • Nonce: Random number
  • Timestamp: Unix timestamp
  • Signature: Concatenate the App Secret, Nonce, and Timestamp in order into a string, then perform an SHA1 hash calculation. The App Secret corresponds to the App Key and can be obtained from the [App Key] page in the RC Console.

If the App Key does not belong to the China (Beijing) Data Center, you must request the overseas API service address.

  • Beijing: api.rong-api.com
  • Singapore: api.sg-light-api.com (primary), api-b.sg-light-api.com (backup)

When obtaining the Token, the HTTP request body must include the user ID (userId), name (name), and avatar (portraitUri).

POST /user/getToken.json HTTP/1.1
Host: api.rong-api.com
App-Key: Your_AppKey
Nonce: 14314
Timestamp: 1408710653491
Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
Content-Type: application/x-www-form-urlencoded

userId=jlk456j5&name=Ironman&portraitUri=http%3A%2F%2Fabc.com%2Fmyportrait.jpg

The user ID supports a combination of uppercase and lowercase letters and numbers, with a maximum length of 64 bytes. Note: The name (name) and avatar (portraitUri) are only used for remote push notifications on mobile devices. If new data is passed when obtaining a new Token, it will overwrite the old name and avatar data.

The response will include the user ID and the corresponding Token. The Token is up to 256 bytes long and can be cached in the app.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"code":200, "userId":"jlk456j5", "token":"sfd9823ihufi"}

Step 4.2: Connect to the Chat Server

After initialization, you can establish an IM connection by passing the user Token obtained in the previous step. The timeLimit parameter specifies the timeout in seconds.

RongCoreClient.connect(userToken, timeLimit, new IRongCoreCallback.ConnectCallback(){
@Override
public void onDatabaseOpened(IRongCoreEnum.DatabaseOpenStatus code) {
if(IRongCoreEnum.DatabaseOpenStatus.DATABASE_OPEN_SUCCESS.equals(code)) {
// Local database opened, navigate to the conversation list page
} else {
// Database opening failed, you can display a toast message.
}
}

@Override
public void onSuccess(String s) {
// Connection successful, if no page navigation occurred in onDatabaseOpened(), you can navigate here.
}

@Override
public void onError(IRongCoreEnum.ConnectionErrorCode errorCode) {
if(errorCode.equals(IRongCoreEnum.ConnectionErrorCode.RC_CONN_TOKEN_EXPIRE)) {
// Request a new token from the app server, and reconnect with the new token after obtaining it
} else if (errorCode.equals(RongCoreClient.ConnectionErrorCode.RC_CONNECT_TIMEOUT)) {
// Connection timed out, display a prompt, and guide the user to retry when the network is stable
} else {
// Other business error codes, handle accordingly based on the error code.
}
}
})

Once the connection is successful, the SDK's reconnection mechanism takes effect. If the connection is lost due to network issues, the SDK will continuously attempt to reconnect until successful, without requiring additional connection operations from you.

Step 5: Join a Chatroom

In RC's chatroom service, you need to create a chatroom and add users to it before users can send and receive messages in the chatroom.

Typically, you create a chatroom via the server-side API, and users join the chatroom via the client SDK. To keep this tutorial simple, we will directly call the client-side API RongChatRoomClient#joinChatRoom, which handles both creating and joining the chatroom in one step.

String chatroomId = "chatroomA";
int defMessageCount = -1;

RongChatRoomClient.getInstance().joinChatRoom(chatroomId, defMessageCount, new IRongCoreCallback.OperationCallback() {

@Override
public void onSuccess() {

}

@Override
public void onError(IRongCoreEnum.CoreErrorCode coreErrorCode) {

}
});

The defMessageCount variable indicates the number of historical messages to fetch when joining the chatroom. A value of -1 means no historical messages will be fetched.

If joining an existing chatroom, you can call the RongChatRoomClient#joinExistChatRoom method.

Step 6: Send Messages

To send messages, use the core class RongCoreClient. Note that the client SDK has a rate limit for sending messages, allowing a maximum of 5 messages per second.

Step 6.1: Construct a Message

All messages can be divided into two categories: regular messages and multimedia messages. The parent class for regular messages is [MessageContent], and for media messages, it is [MediaMessageContent]. The main difference between sending media messages and regular messages is the data upload process.

Regular messages typically refer to text messages. The following example constructs a text message.

String targetId = "Chatroom ID";
ConversationType conversationType = Conversation.ConversationType.CHATROOM;
TextMessage messageContent = TextMessage.obtain("Hello");
Message message = Message.obtain(targetId, conversationType, messageContent);

Media messages generally include image messages, GIFs, etc. The following example constructs an image message.

String targetId = "Chatroom ID";
ConversationType conversationType = Conversation.ConversationType.CHATROOM;
Uri localUri = Uri.parse("file://Path to the image"); // Local path of the image, the recipient can get the automatically generated thumbnail Uri via getThumUri
boolean mIsFull = true; // Whether to send the original image
ImageMessage mediaMessageContent = ImageMessage.obtain(localUri, mIsFull);
Message message = Message.obtain(targetId, conversationType, channelId, mediaMessageContent);

Step 6.2: Send a Message

To send messages that do not involve media file uploads, such as RC's built-in message types like text messages, or custom messages that do not involve the media file upload process, use the sendMessage method.

RongCoreClient.getInstance().sendMessage(message, null, null, new IRongCoreCallback.ISendMessageCallback() {

@Override
public void onAttached(Message message) {

}

@Override
public void onSuccess(Message message) {

}

@Override
public void onError(Message message, IRongCoreEnum.CoreErrorCode errorCode) {

}
});

To send media messages, use the sendMediaMessage method. This method first uploads the media file (image, video, etc.) to RC's default file server (File Storage Duration), and then sends the message after the upload is successful.

RongCoreClient.getInstance().sendMediaMessage(message, null, null, new IRongCoreCallback.ISendMediaMessageCallback() {
@Override
public void onProgress(Message message, int i) {

}

@Override
public void onCanceled(Message message) {

}

@Override
public void onAttached(Message message) {

}

@Override
public void onSuccess(Message message) {

}

@Override
public void onError(final Message message, final IRongCoreEnum.CoreErrorCode errorCode) {

}
});

Step 7: Save Historical Messages

The local chatroom messages of the current user are automatically deleted when the user exits the chatroom. Before exiting the chatroom, you can retrieve the local historical message records. By enabling the Chatroom Message Cloud Storage service, chatroom messages can be stored on the RC server. The client can directly retrieve messages stored on the server.

Typically, you first call getHistoryMessages to retrieve local historical records. If the result is empty, then call getChatroomHistoryMessages to retrieve remote historical records. Note that getChatroomHistoryMessages does not return messages that already exist in the local database.

Conversation.ConversationType conversationType = Conversation.ConversationType.CHATROOM;
int oldestMessageId = -1;
final int count = 10;

final String targetId = "Chatroom ID";
final long recordTime = 0;

RongCoreClient.getInstance().getHistoryMessages(conversationType, targetId, oldestMessageId, count,
new IRongCoreCallback.ResultCallback<List<Message>>() {

@Override
public void onSuccess(List<Message> messages) {
if (messages == null || messages.isEmpty()) {
RongChatRoomClient.getInstance().getChatroomHistoryMessages(targetId, recordTime, count, IRongCoreEnum.TimestampOrder.RC_TIMESTAMP_ASC,
new IRongCoreCallback.IChatRoomHistoryMessageCallback() {

@Override
public void onSuccess(List<Message> messages, long syncTime) {

}


@Override
public void onError(IRongCoreEnum.CoreErrorCode code) {

}
});

}
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode errorCode) {

}
});

An oldestMessageId of -1 indicates that the query starts from the latest local message.

getChatroomHistoryMessages returns the fetched historical message array and syncTime in the success callback. If the fetch order is RC_Timestamp_Desc, syncTime is the timestamp of the earliest message in the fetch result (i.e., the smallest timestamp). If the fetch order is RC_Timestamp_Asc, syncTime is the timestamp of the latest message in the fetch result (i.e., the largest timestamp). If the fetch order remains unchanged, the syncTime value returned in the current fetch can be passed as recordTime in the next fetch to facilitate continuous fetching.

Step 8: Recall a Message

If an app administrator or a regular user wants to delete a message from all chatroom members' chat history, the message recall feature can be used. Once a message is successfully recalled, the original message content is deleted from all users' local and server-side historical message records.

Message message = Message.obtain("123", ConversationType.GROUP, "12345");

RongCoreClient.getInstance().recallMessage(message, "", new IRongCoreCallback.ResultCallback<RecallNotificationMessage>() {
/**
* Success callback
*/
@Override
public void onSuccess(RecallNotificationMessage recallNotificationMessage) {

}

/**
* Failure callback
* @param errorCode Error code
*/
@Override
public void onError(IRongCoreEnum.CoreErrorCode errorCode) {

}
});

Step 9: Ban Users

The Instant Messaging service supports various ban and mute capabilities. The client does not provide related APIs; you need to implement them via the server-side API.

Ban a Specific User

Ban an app user. A single request can ban up to 20 user IDs (userId). The minute parameter represents the ban duration, with a maximum of 43200 minutes. Once banned, the banned user is immediately disconnected from the IM service. During the ban period, the user cannot establish an IM connection with RC or actively use the IM service.

  • Ban:

    POST /user/block.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&minute=10
  • Unban:

    POST /user/unblock.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA

Mute a Chatroom User

The chatroom service supports muting users. A single request can mute up to 20 users (userId) in a specified chatroom (chatroomId). The minute parameter represents the mute duration, with a maximum of 43200 minutes. Muted users can receive and view messages from other users in the chatroom but cannot send messages to the chatroom via the client SDK. Exiting the chatroom does not end the mute status.

  • Mute:

    POST /chatroom/user/gag/add.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&chatroomId=16&minute=1
  • Unmute:

    POST /chatroom/user/gag/rollback.json HTTP/1.1
    Host: api.rong-api.com
    App-Key: uwd1c0sxdlx2
    Nonce: 14314
    Timestamp: 1408710653491
    Signature: 45beb7cc7307889a8e711219a47b7cf6a5b000e8
    Content-Type: application/x-www-form-urlencoded

    userId=UserA&chatroomId=16

Mute a