Connect to server
Your app must establish a connection to the Nexconn server before it can send and receive messages through the Chat SDK. When the server receives a connection request, it validates the user's access token to determine whether to allow the connection.
Prerequisites
- Obtain an access token — Call the server-side API to register a user and obtain an access token. The Chat SDK does not provide a method to generate access tokens. Your app server must request the token from the Nexconn server, then pass it to the client.
- Cache the access token on the client for subsequent connections. If the token has not expired, there is no need to request a new one.
- Configure token expiration in the Console. Tokens are permanent by default. Even after generating a new token, any unexpired old token remains valid. To revoke a token manually, call the server-side API to expire the token.
- Set up a connection status listener — Register a connection status handler before connecting.
- Initialize the SDK — Ensure
NCEngine.initialize()has been called.
Never call the server-side API to obtain access tokens directly from the client. Doing so requires embedding your App Key and App Secret in the client code, which exposes these credentials if the app is decompiled. Always obtain access tokens from your own app server.
Connect to the chat server
Initiate a connection to the Nexconn chat server at the appropriate point in your app's flow (for example, after login or registration).
Keep the following in mind:
- Call
connectonly after the SDK is initialized, otherwise the callback may not fire. - Do not call
connectmultiple times within a single app lifecycle. The SDK has a built-in reconnection mechanism, and repeated calls may trigger multiple callbacks or cause callbacks to be cleared. - Call
connectonce from the main process.
- Kotlin
- Java
// Basic usage
NCEngine.connect(ConnectParams("user-token")) { userId, error ->
if (error == null) {
// Connection successful — userId is the current user's ID
Log.d("Connect", "Connected: $userId")
} else {
// Connection failed
handleConnectError(error)
}
}
// With timeout (recommended for first-time connections)
NCEngine.connect(ConnectParams("user-token").apply {
timeout = 10 // 10-second timeout
}) { userId, error ->
when {
error == null -> {
Log.d("Connect", "Connected: $userId")
}
error.code == 34006 -> {
// Connection timed out
showTip("Connection timed out. Check your network and try again.")
}
error.code == 31020 -> {
// Access token expired — refresh and reconnect
refreshTokenAndConnect()
}
else -> {
showTip("Connection failed: ${error.message}")
}
}
}
// Basic usage
ConnectParams params = new ConnectParams("user-token");
NCEngine.connect(params, new ConnectHandler() {
@Override
public void onResult(String userId, NCError error) {
if (error == null) {
Log.d("Connect", "Connected: " + userId);
} else {
handleConnectError(error);
}
}
});
// With timeout
ConnectParams params = new ConnectParams("user-token");
params.setTimeout(10); // 10-second timeout
NCEngine.connect(params, new ConnectHandler() {
@Override
public void onResult(String userId, NCError error) {
if (error == null) {
Log.d("Connect", "Connected: " + userId);
} else if (error.getCode() == 34006) {
showTip("Connection timed out. Check your network and try again.");
} else if (error.getCode() == 31020) {
refreshTokenAndConnect();
} else {
showTip("Connection failed: " + error.getMessage());
}
}
});
Parameters
ConnectParams accepts the following properties:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| token | String | Yes | - | The access token obtained from your server |
| timeout | Int | No | -1 | Connection timeout in seconds. • ≤ 0: No timeout. The SDK keeps trying until it connects or encounters a business error. • > 0: Stops reconnecting after the specified time and returns a timeout error. |
| reconnectKickEnable | Boolean | No | false | Controls the reconnection device conflict policy. When false (default), the reconnecting device kicks out any already-connected device. When true, the reconnecting device stops if another device is already online, preserving the existing session. |
Recommended patterns
First-time connection (user login):
- Kotlin
- Java
// Set a timeout to handle network issues gracefully
NCEngine.connect(ConnectParams(token).apply {
timeout = 10
}) { userId, error ->
// Handle connection result
}
// Set a timeout to handle network issues gracefully
ConnectParams params = new ConnectParams(token);
params.setTimeout(10);
NCEngine.connect(params, (userId, error) -> {
// Handle connection result
});
Handle the database opened event:
The ConnectHandler also exposes an onDatabaseOpened callback, which fires when the local database is ready (before onResult). Override it to know the earliest moment local data is accessible:
- Kotlin
- Java
NCEngine.connect(ConnectParams(token), object : ConnectHandler {
override fun onDatabaseOpened(isRecreated: Boolean, error: NCError?) {
if (error == null) {
// Local database is ready — safe to access local data
if (isRecreated) {
// Database was recreated; local data was cleared
}
}
}
override fun onResult(userId: String?, error: NCError?) {
if (error == null) {
println("Connected: $userId")
}
}
})
NCEngine.connect(new ConnectParams(token), new ConnectHandler() {
@Override
public void onDatabaseOpened(boolean isRecreated, @Nullable NCError error) {
if (error == null) {
// Local database is ready — safe to access local data
if (isRecreated) {
// Database was recreated; local data was cleared
}
}
}
@Override
public void onResult(@Nullable String userId, @Nullable NCError error) {
if (error == null) {
System.out.println("Connected: " + userId);
}
}
});
For database schema upgrade events fired during SDK version upgrades, see Database events.
Offline login (cached data available):
- Kotlin
- Java
// No timeout — let the SDK reconnect automatically
NCEngine.connect(ConnectParams(token)) { userId, error ->
// Display local data first; the SDK syncs automatically once connected
}
// No timeout — let the SDK reconnect automatically
NCEngine.connect(new ConnectParams(token), (userId, error) -> {
// Display local data first; the SDK syncs automatically once connected
});
Connection error codes
When a connection fails, the NCError object contains an error code and message. The table below lists the most common error codes.
| Error code | Description |
|---|---|
-2 | IPC process terminated unexpectedly. Possible causes: • The system reclaimed or unbound the IPC process • The matching CPU architecture libRongIMLib.so or libsqlite.so was not foundAction: The SDK reconnects automatically. No action required. |
31002 | Invalid App Key. Action: Verify the App Key used during initialization. |
31004 | Invalid access token. Action: Ensure the App Key used for initialization matches the one used to generate the access token on the server. |
31005 | App verification failed. Action: Check whether app verification is enabled and configured correctly. |
31008 | App is banned or deleted. Action: Check the app status associated with your App Key. |
31009 | User is banned. Action: Check whether the user ID associated with this access token has been banned. |
31020 | Access token expired. Action: Request a new access token from the server and reconnect. |
31028 | Proxy server unreachable. Action: Check your network proxy configuration. |
33001 | SDK not initialized. Action: Call NCEngine.initialize() before using any SDK features. |
34001 | A connection already exists or reconnection is in progress. Action: Do not call connect() again. The SDK is already reconnecting. |
34006 | Connection timed out. Action: Check the network and prompt the user to retry. |
-1 | Unknown error. Action: Inspect error.message for details. |
Error handling example
- Kotlin
- Java
NCEngine.connect(ConnectParams(token)) { userId, error ->
if (error != null) {
when (error.code) {
31020 -> {
// Access token expired
refreshTokenAndConnect()
}
31009 -> {
// User banned
showMessage("Your account has been banned. Contact support.")
}
34006 -> {
// Connection timed out
showMessage("Connection timed out. Check your network and try again.")
}
33001 -> {
// SDK not initialized
initializeSDKAndConnect()
}
else -> {
showMessage("Connection failed: ${error.message}")
}
}
}
}
NCEngine.connect(new ConnectParams(token), (userId, error) -> {
if (error != null) {
switch (error.getCode()) {
case 31020:
// Access token expired
refreshTokenAndConnect();
break;
case 31009:
// User banned
showMessage("Your account has been banned. Contact support.");
break;
case 34006:
// Connection timed out
showMessage("Connection timed out. Check your network and try again.");
break;
case 33001:
// SDK not initialized
initializeSDKAndConnect();
break;
default:
showMessage("Connection failed: " + error.getMessage());
}
}
});