Introduction
Since LeanCloud released its real-time communication (IM) service last year, based on user feedback, engineers' digestion of demand and business refinement, "Real-time Communication 2.0" was officially released last week. The design concept is still "flexible, decoupled, combinable, and customizable". For details, please refer to the "Real-Time Communication Development Guide" to understand the basic concepts and models of LeanCloud's real-time communication.
Download and install
You can download the LeanCloud IM SDK v2 version at the official LeanCloud download point. Add the downloaded jar package to the project.
One-to-one text chat
Let’s start with the simplest link and see how to implement one-to-one text chat using LeanCloud IM SDK v2.
initialization
Like other LeanCloud services, the initialization of the live chat service is also performed in the Application's onCreate method:
public class MyApplication extends Application{
public void onCreate(){
...
(this,"{{appId}}","{{appKey}}");
...
}
}
And declare in the middle:
<manifest>
...
<application
android:name=".MyApplication"
....>
...
<service android:name="" />
<receiver android:name="">
<intent-filter>
<action android:name=".BOOT_COMPLETED" />
<action android:name=".USER_PRESENT" />
</intent-filter>
</receiver>
...
</application>
</manifest>
Next we need to complete the user login.
Log in
Assuming that the initiator of the chat is Tom, for intuitive reasons, we use the user name to log in to the chat system as clientId (LeanCloud cloud only requires clientId to be unique in the application, and the specific data to be used is determined by the application layer). The code is as follows:
AVIMClient imClient = ("Tom");
(new IMClientCallback(){
@Override
public void done(AVIMClient client, AVException e) {
if (e) {
// An error may be caused by a network problem. You cannot connect to LeanCloud cloud. Please check the network and try again.
// The chat service is not available at this time.
} else {
// After successfully logging in, you can start chatting.
};
}
});
Create a conversation
Suppose we want to chat with the user "Bob", we first create a conversation with the following code:
// The following code contains all the logic in the actual application: Query -> Create "Dialogue".
// Check whether there is a private chat conversation with "Bob". You can ignore this part of the code first
List<String> clientIds = new ArrayList<String>();
("Tom");
("Bob");
AVIMConversationQuery conversationQuery = ();
(clientIds);
// There was a constant definition before:
// int ConversationType_OneOne = 0; // Single chat between two people
// int ConversationType_Group = 1; // Group chat between multiple people
("", ConversationType_OneOne);
(new AVIMConversationQueryCallback(){
@Override
public void done(List<AVIMConversation> conversations, AVException e) {
if (null != e) {
// Something went wrong. . .
} else if (null != conversations && () > 0){
// There is already a conversation with Bob, and continue chatting in this conversation
...
} else {
// I have never talked to Bob, create a new conversation. ! ! **This is the key point**! !
Map<String, Object> attr = new HashMap<String, Object>();
("type", ConversationType_OneOne);
(clientIds, attr, new AVIMConversationCreatedCallback() {
@Override
public void done(AVIMConversation conversation, AVException e) {
if (null != conversation) {
// Success!
}
}
});
}
}
});
How to query "Dialogue"
As you can see, when we create a conversation, we specify members (Tom and Bob) and an additional attribute ({type: 0}). After these data are saved to the cloud, you will see in the console -> Storage -> Data that a record has been added to the _Conversation table. The m attribute value of the new record is ["Tom", "Bob"], and the attr attribute value is {"type":0}. As you might expect, the m attribute corresponds to the member list, and the attr attribute is the additional attribute value added by the user (stored as an object).
Like the search method of AVObject, to retrieve such a conversation, we need to obtain an AVIMConversationQuery instance through () and then call () to qualify the member list and call () to qualify the additional attr attribute. According to AVQuery convention, the attribute name that needs to be specified when qualifying additional type conditions is .
Send a message
After establishing a conversation, it is very easy to send a message:
AVIMMessage message = new AVIMMessage();
("hello");
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
OK, this message is sent. But the question is, for "Bob", how can he receive messages from others?
Message reception
On the Bob side, to be able to receive messages, the following steps are required:
1. Initialize and log in, the code is no different from the sender;
2. Implement your own AVIMMessageHandler to respond to the arrival notification of new messages, mainly the following functions:
public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client);
To display the message sent by Tom, we only need to implement onMessage, the sample code is as follows:
class CustomMessageHandler extends AVIMMessageHandler {
@Override
public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client) {
// New news is here. Add your own processing code here.
...
}
}
(new CustomMessageHandler());
Several main callback interfaces
From the example above, we can see that to receive messages sent to you by others, you need to implement your own AVIMMessageHandler class. Starting from v2, the LeanCloud IM SDK uses callbacks to feedback operation results, but for some passive message notifications, it is still implemented using interfaces, including:
The current network changes
There is new news in the conversation
New members joined in the conversation
A member left during the conversation
Invited to join a conversation
Kicked out of the conversation
The LeanCloud IM SDK uses three interfaces internally to respond to these events.
Network incident response interface (AVIMClientEventHandler)
It is mainly used to deal with network change events, and the main functions are:
/**
* Implement this method to handle network disconnection events
*
* @param client
* @since 3.0
*/
public abstract void onConnectionPaused(AVIMClient client);
/**
* Implement this method to handle network recovery events
*
* @since 3.0
* @param client
*/
public abstract void onConnectionResume(AVIMClient client);
In the event of network outage, all messaging and dialogue operations will have problems.
The global ClientEventHandler can be set through (AVIMClientEventHandler handler).
Dialogue member change response interface (AVIMConversationEventHandler)
It is mainly used to deal with events that change members in conversations, and the main functions are:
/**
* Implement this method to handle participant departure events in chat conversations
*
* @param client
* @param conversation
* @param members Leaving participants
* @param kickedBy The initiator of the departure event may be the participant himself who left
* @since 3.0
*/
public abstract void onMemberLeft(AVIMClient client,
AVIMConversation conversation, List<String> members, String kickedBy);
/**
* Implement this method to handle participant joining events in chat conversations
*
* @param client
* @param conversation
* @param members Participants
* @param invitedBy The invitation to join the event may be the participant himself
* @since 3.0
*/
public abstract void onMemberJoined(AVIMClient client,
AVIMConversation conversation, List<String> members, String invitedBy);
/**
* Implement this method to handle the current user being kicked out of a chat conversation event
*
* @param client
* @param conversation
* @param kickedBy Kick out your person
* @since 3.0
*/
public abstract void onKicked(AVIMClient client, AVIMConversation conversation,
String kickedBy);
/**
* Implement this method to handle the current user being invited to a chat conversation event
*
* @param client
* @param conversation Invited chat conversation
* @param operator Invite your person
* @since 3.0
*/
public abstract void onInvited(AVIMClient client, AVIMConversation conversation,
String operator);
The global ConversationEventHandler can be set through (AVIMConversationEventHandler handler).
MessageHandler
It is mainly used to handle new message arrival events, the main functions are:
// Received a new message
@Override
public abstract void onMessage(AVIMMessage message, AVIMConversation conversation);
// The message you sent by yourself has been received by the other party
@Override
public abstract void onMessageReceipt(AVIMMessage message, AVIMConversation conversation, AVIMClient client);
The global MessageHandler can be set through (MessageHandler handler).
When we implement these three types of interfaces, we can handle all notification messages (note: LeanCloud IM SDK implements an empty AVIMMessageHandler internally, and you can derive the handler from here for actual processing).
Support rich media chat messages
The above code demonstrates how to send simple text information, but now the interaction methods are becoming more and more diverse, and pictures, voice, and video are already very common types of message. The LeanCloud IM SDK for v2 can already support these rich media messages well, as detailed below:
Base class: AVIMTypedMessage
The base class for all rich media messages, which is declared as
//The message type defined by the SDK, the type used by the LeanCloud SDK itself is a negative number, and all positive numbers are left to the developer to use for custom extension types, and 0 is retained as "no type".
enum AVIMReservedMessageType {
UnsupportedMessageType(0),
TextMessageType(-1),
ImageMessageType(-2),
AudioMessageType(-3),
VideoMessageType(-4),
LocationMessageType(-5),
FileMessageType(-6);
};
public abstract class AVIMTypedMessage extends AVIMMessage {
public AVIMTypedMessage();
public int getMessageType();
@Override
public final String getContent();
@Override
public final void setContent(String content);
}
Text Message (AVIMTextMessage)
AVIMTypedMessage subclass, represents a general text message, declared as
@AVIMMessageType(type = -1)
public class AVIMTextMessage extends AVIMTypedMessage {
public String getText();
public void setText(String text);
public Map<String, Object> getAttrs();
public void setAttrs(Map<String, Object> attr);
}
To send a text message, the sample code is:
AVIMTextMessage message = new AVIMTextMessage();
("hello");
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
Image Message (AVIMImageMessage)
AVIMTypedMessage subclass supports sending mixed messages with pictures and accompanying text, which is declared as:
public class AVIMImageMessage extends AVIMFileMessage {
public AVIMImageMessage();
public AVIMImageMessage(String localPath) throws FileNotFoundException, IOException;
public AVIMImageMessage(File localFile) throws FileNotFoundException, IOException;
public AVIMImageMessage(AVFile file);
/**
* Get the metaData of the file
*
* @return
*/
@Override
public Map<String, Object> getFileMetaData();
/**
* Get the image height
*
* @return
*/
public int getHeight();
/**
* Get the width of the image
*
* @return
*/
public int getWidth();
}
The example code for sending image messages is:
String localImagePath;
try {
AVIMImageMessage message = new AVIMImageMessage(localImagePath);
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
} catch (Exception ex) {
}
After receiving such a message, the developer can obtain several image metadata (width, height, image size, image format) and an AVFile object containing image data.
Audio Message (AVIMAudioMessage)
AVIMTypedMessage subclass, supports sending mixed messages with voice and accompanying text, declared as:
public class AVIMAudioMessage extends AVIMFileMessage {
public AVIMAudioMessage();
public AVIMAudioMessage(String localPath) throws FileNotFoundException, IOException;
public AVIMAudioMessage(File localFile) throws FileNotFoundException, IOException;
public AVIMAudioMessage(AVFile file);
/**
* Get the metaData of the file
*
* @return
*/
@Override
public Map<String, Object> getFileMetaData();
/**
* Duration of audio acquisition
*
* @return
*/
public double getDuration();
}
The example code for sending audio messages is:
String localAudioPath;
try {
AVIMAudioMessage message = new AVIMAudioMessage(localAudioPath);
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
} catch (Exception ex) {
}
After receiving such a message, the developer can obtain several audio metadata (duration, audio size, audio format) and an AVFile object containing the audio data.
Video Message (AVIMVideoMessage)
AVIMTypedMessage subclass, supports sending mixed messages with video and accompanying text, declared as:
public class AVIMVideoMessage extends AVIMFileMessage {
public AVIMVideoMessage();
public AVIMVideoMessage(String localPath) throws FileNotFoundException, IOException;
public AVIMVideoMessage(File localFile) throws FileNotFoundException, IOException;
public AVIMVideoMessage(AVFile file);
/**
* Get the metaData of the file
*
* @return
*/
@Override
public Map<String, Object> getFileMetaData();
/**
* Retrieval time
*
* @return
*/
public double getDuration();
}
The example code for sending video messages is:
String localVideoPath;
try {
AVIMVideoMessage message = new AVIMVideoMessage(localVideoPath);
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
} catch (Exception ex) {
}
After receiving such a message, the developer can obtain several video metadata (duration, video size, video format) and an AVFile object containing video data.
Geographic location message (AVIMLocationMessage)
AVIMTypedMessage subclass supports sending mixed messages with geolocation information and accompanying text, which is declared as:
public class AVIMLocationMessage extends AVIMTypedMessage {
public String getText();
public void setText(String text);
public Map<String, Object> getAttrs();
public void setAttrs(Map<String, Object> attr);
public AVGeoPoint getLocation();
public void setLocation(AVGeoPoint location);
}
The example code to send a location message is:
AVIMLocationMessage message = new AVIMLocationMessage();
("Come here quickly!");
(new AVGeoPoint(15.9, 56.4));
(message, new AVIMConversationCallback() {
@Override
public void done(AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
}
}
});
After receiving such a message, the developer can obtain specific geographical location data.
How to receive rich media messages
The new LeanCloud IM SDK internally encapsulates support for rich media messages, all rich media messages derived from AVIMTypedMessage. You can call the function directly when sending. On the receiving side, we also added a type of callback interface:
public class AVIMTypedMessageHandler<T extends AVIMTypedMessage> extends MessageHandler<T> {
@Override
public void onMessage(T message, AVIMConversation conversation, AVIMClient client);
@Override
public void onMessageReceipt(T message, AVIMConversation conversation, AVIMClient client);
}
Developers can write their own message processing handler and then call the (Class<? extends AVIMMessage> clazz, MessageHandler<?> handler) function to register the target handler.
The logic of internal message distribution of LeanCloud IM SDK is as follows: For any new message received, the SDK will first parse the message type, find the handler registered by the developer for this type according to the type, and then call the onMessage function of these handlers one by one. If no handler is found specifically for processing this type of message, it will be handed over to defaultHandler for processing.
In this way, when the developer specifies a special handler for TypedMessage (and its subclass) and also specifies a global defaultHandler, if the sender sends a general AVIMMessage message, then the acceptor is the handler specified in () is called; if the message sent is an AVIMTypedMessage (and its subclass) is called, then the acceptor is the handler specified in () is called.
The receiving end's notification processing code snippet for rich media messages is as follows:
class MsgHandler extends AVIMTypedMessageHandler {
@Override
public void onMessage(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {
getInstance().onMessage(conversation, message);
}
@Override
public void onMessageReceipt(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {
getInstance().onMessageDelivered(message);
}
}
MsgHandler msgHandler = new MsgHandler();
(, msgHandler);
How to expand your own rich media messages
Inherited from AVIMTypedMessage, developers can also expand their own rich media messages. This part is high-level content. If you are interested, you can refer to this document. I will not go into details here.
Group Chat
Similar to the previous single chat, group chat also requires a conversation (AVIMConversation) first, and then send and receive new messages.
Create a group
Similar to single chat, it is also very simple to create a group with multiple people chatting. For example:
Map<String, Object> attr = new HashMap<String, Object>();
("type", ConversationType_Group);
(clientIds, attr, new AVIMConversationCreatedCallback() {
@Override
public void done(AVIMConversation conversation, AVException e) {
if (null != conversation) {
// Success!
}
}
});
After success, we can enter the chat interface.
Send messages to the group
Sending messages is very simple, just like the previous single chat scenario.
We will notice that AVIMConversation also has a method to send messages:
public void sendMessage(final AVIMMessage message, final int messageFlag,
final AVIMConversationCallback callback)
Here, the definition of flag is as follows:
Transient message (AVIMConversation.TRANSIENT_MESSAGE_FLAG). This kind of message will not be automatically saved (it will not be found in historical messages in the future), nor will it support delayed reception, and offline users will not receive push notifications, so it is suitable for use as a control protocol. For example, status information such as "Someone is entering..." during the chat process is suitable for sending through a transient message.
Normal message (AVIMConversation.NONTRANSIENT_MESSAGE_FLAG). This kind of message is the most commonly used message type. It will be saved automatically in LeanCloud cloud, supporting delayed reception and offline push, and you can find it in historical messages in the future.
A pending receipt message (AVIMConversation.RECEIPT_MESSAGE_FLAG). This is also a kind of ordinary message, but after the message is received by the other party, the LeanCloud server will send a receipt notification to the sender (this is the time when the public void onMessageReceipt(AVIMMessage message, AVIMConversation conversation, AVIMClient client) function is called in AVIMMessageHandler).
Receive group messages
Receiving messages from a group is the same as receiving messages from a single chat.
Member Management
After querying chat room members, users can invite some of their own friends to join, and as administrators, they can also eliminate some "terrible" members.
The API for joining new members is as follows:
List<String> userIds = new ArrayList<String>();
("A");
("B");
("C");
(userIds, new AVIMConversationCallback() {
@Override
public void done(AVException error) {
if (null != error) {
// Failed to join, an error was reported.
} else {
// Send an invitation, and after that new members can see all the messages in this conversation.
}
}
});
After the invitation is successful, the notification process is as follows:
Operator (Administrator) Invited person
1, issue a request addMembers
2,
3. Receive onMemberJoined notification Receive onMemberJoined notification Receive onMemberJoined notification
Accordingly, the calling API when kicking someone is:
List<String> userIds = new ArrayList<String>();
("A");
(userIds, new AVIMConversationCallback() {
@Override
public void done(AVException error) {
if (null != error) {
// Failed, an error was reported.
} else {
// success.
}
}
});
The notification process for kicking people is as follows:
Operator (Administrator) The person kicked
1, issue a request kickMembers
2,
3. Received onMemberLeft notification
Notice!
If the invitation or kicking operation occurs, the invitee/kicked person is not currently online, the notification message will not be cached offline, so they will not receive notifications when they go online again.
Get historical messages
LeanMessage will automatically save non-transitory messages in the cloud, and then developers can obtain all historical messages of the conversation through AVIMConversation. The API for obtaining historical messages is as follows:
String oldestMsgId;
long oldestMsgTimestamp;
(oldestMsgId,oldestMsgTimestamp, limit, new AVIMHistoryMessageCallback(){
@Override
public void done(List<AVIMMessage> messages, AVException e) {
if (null != e) {
// An error occurred:(
} else {
// success
}
}
});
Notice:
When obtaining historical messages, LeanCloud cloud starts with a certain message, searches forward for N messages specified by the developer, and returns them to the client. To obtain historical messages, three parameters need to be passed in: msgId of the start message, the sending timestamp of the start message, and the number of message lines to be obtained.
The messages obtained through this API are AVIMMessage or AVIMTypedMessage instance arrays, and developers can handle them like they received new messages notifications before.
Enable offline message push (only valid for iOS platform users)
Whether it is a single chat or a group chat, when User A sends a message, if some users in the target conversation are not currently online, LeanCloud cloud can provide offline push to remind users. This feature is turned off by default, and you can turn it on in the LeanCloud app console. The method to enable it is as follows:
Log in to the LeanCloud application console and select the correct application to enter;
Select the top "Message" service, click "Real-time Message"->"Settings" menu on the left;
Fill in the message content you want to push out under "Pused content when iOS users are offline" on the right and save it;
In this way, users on the iOS platform can receive Push Notification (of course, the premise is that the application itself applies for RemoteNotification permission and uploads the correct push certificate to the LeanCloud console).
Group messages do not interrupt (only valid for iOS platform users)
Whether it is a single chat or a group chat, for ordinary messages sent to ordinary Conversation, if the recipient is not currently online, LeanCloud cloud supports reminding through Push Notification. Generally, this is very good, but if a group is particularly active, offline users will receive too many pushes, which will cause considerable interference.
For this, the LeanCloud IM service also allows a single user to turn off/on a conversation's offline push feature. The calling API is as follows:
if (open) {
[_conversation muteWithCallback:^(BOOL succeeded, NSError *error) {
...
}];
} else {
[_conversation unmuteWithCallback:^(BOOL succeeded, NSError *error) {
...
}];
}
Search Groups
Whether it is a single chat or a group chat, there is a conversation in the LeanCloud IM SDK. We set the following attributes for the conversation:
conversationId, string, dialogue id, read-only, after the dialogue is created, a globally unique id is given by the LeanCloud cloud.
creator, string, dialogue creator id, read-only, identify dialogue creator information
Members, arrays, conversation participants, all participants are recorded here
name, string, dialogue name, optional, can be used to name groups
attributes, Map/Dict, custom attributes, optional, for developers to expand themselves.
We provide specialized classes to search for specific groups. For example, to search for all group chat conversations that the currently logged in user participates in, the code is
List<String> clients = new ArrayList<String>();
("Tom");
AVIMConversationQuery conversationQuery = ();
(clients);
// There was a constant definition before:
// const int ConversationType_OneOne = 0;
// const int ConversationType_Group = 1;
("", ConversationType_Group);
(new AVIMConversationQueryCallback(){
@Override
public void done(List<AVIMConversation> conversations, AVException e) {
if (null != e) {
// Something went wrong. . .
} else {
// done!
}
}
});
The method of setting conditions in AVIMConversationQuery is similar to AVQuery. For details, please refer to its header file. One thing to emphasize here is that for the constraints of custom attributes, the attribute name must start with attr.
Open chat room
Open chat rooms (also called transient dialogue) can be used in many places, such as barrage, live broadcast, etc. In the LeanCloud IM SDK, open chat rooms are a special type of group. It also supports operations such as creating, joining/kicking out members. Message records will be saved and available for acquisition; the differences from ordinary groups are specifically reflected in:
Querying member list is not supported, you can query the number of online users through the relevant API;
It does not support offline messages, offline push notifications and other functions;
No notice of membership or departure;
A user can only join one open chat room at a time, and after joining a new open chat room, it will automatically leave the original chat room;
If you disconnect the Internet and reconnect within half an hour after joining, you will automatically join the original chat room. If you exceed this time, you will need to join again;
Create an open chat room
Similar to ordinary groups, it is also very simple to create an open chat room, except that in (conversationMembers, name, attributes, isTransient, callback) we need to pass in the isTransient=true option. For example:
Map<String, Object> attr = new HashMap<String, Object>();
("type", ConversationType_Group);
(clientIds, name, attr, true, new AVIMConversationCreatedCallback() {
@Override
public void done(AVIMConversation conversation, AVException e) {
if (null != conversation) {
// Success!
}
}
});
After joining successfully, we can enter the chat interface. Other operations in open chat rooms are the same as those in ordinary group operations.
Check the number of online users
The () method can be used to query the number of online people in the open chat room in real time. The sample code is as follows:
(new AVIMConversationMemberCountCallback(){
@Override
public void done(Integer memberCount, AVException e) {
if (null != e) {
// An error occurred:(
} else {
// Success, at this time the value of memberCount is the real-time number of online users
}
}
});
Signature and security
In order to meet developers' requirements for permissions and authentication, LeanCloud also designed a mechanism for operating signatures. We can enable signature by checking "Chat Service Signature Authentication" under "Settings" -> "App Options" -> "Chat Push" in the LeanCloud application console (this is highly recommended). After enabled, all user login, conversation creation/joining, inviting members, kicking out members and other operations need to verify the signature, so that developers can fully control the messages.
How should the client be used? We only need to implement the SignatureFactory interface, and then assign the instance of this interface to AVIMClient before the user logs in ((factory)).
After setting up the signatureFactory, for operations that require authentication, LeanCloud IM SDK will bring the Signature information generated by the application when communicating with the server. LeanCloud cloud will use the app's masterKey to verify the validity of the information and ensure the security of the chat channel.
For the SignatureFactory interface, we only need to implement these two functions:
/**
* Implement a basic signature method. The signature algorithm in it will be used in SessionManager and AVIMClient(V2)
*
* @param peerId
* @param watchIds
* @return
* @throws SignatureException If any problem occurs in the signature calculation, please throw this exception
*/
public Signature createSignature(String peerId, List<String> watchIds) throws SignatureException;
/**
* Implement signature calculation related to AVIMConversation
*
* @param conversationId
* @param clientId
* @param targetIds The data corresponding to the operation
* @param action
* @return
* @throws SignatureException If any problem occurs in the signature calculation, please throw this exception
*/
public Signature createConversationSignature(String conversationId, String clientId,
List<String> targetIds, String action) throws SignatureException;
The createSignature function will be called when the user logs in, and createConversationSignature will be called when the conversation creates/joins, invites members, kicks out members, etc.
All you need to do is implement signature according to the signature algorithm described above, where the Signature declaration is as follows:
public class Signature {
public List<String> getSignedPeerIds();
public void setSignedPeerIds(List<String> signedPeerIds);
public String getSignature();
public void setSignature(String signature);
public long getTimestamp();
public void setTimestamp(long timestamp);
public String getNonce();
public void setNonce(String nonce);
}
The four attributes are:
signature
timestamp timestamp, unit seconds
nonce random string nonce
signedPeerIds release clientId list, which is already abandoned in v2
The following code shows the implementation snippet of the client when signing based on LeanCloud cloud code:
public class KeepAliveSignatureFactory implements SignatureFactory {
@Override
public Signature createSignature(String peerId, List<String> watchIds) {
Map<String,Object> params = new HashMap<String,Object>();
("self_id",peerId);
("watch_ids",watchIds);
try{
Object result = ("sign",params);
if(result instanceof Map){
Map<String,Object> serverSignature = (Map<String,Object>) result;
Signature signature = new Signature();
((String)("signature"));
((Long)("timestamp"));
((String)("nonce"));
return signature;
}
}catch(AVException e){
throw () e;
}
return null;
}
@Override
public Signature createConversationSignature(String convId, String peerId, List<String> targetPeerIds,String action){
Map<String,Object> params = new HashMap<String,Object>();
("self_id",peerId);
("group_id",convId);
("group_peer_ids",targetPeerIds);
("action",action);
try{
Object result = ("group_sign",params);
if(result instanceof Map){
Map<String,Object> serverSignature = (Map<String,Object>) result;
Signature signature = new Signature();
((String)("signature"));
((Long)("timestamp"));
((String)("nonce"));
return signature;
}
}catch(AVException e){
throw () e;
}
return null;
}
}
LeanCloud IM SDK focuses on providing basic communication services, with more customizations, such as:
The account system and the IM system are separated;
When messages become offline push, developers can customize the content push;
Through web hooks, developers can process messages more;
During the chat process, developers can have more control through the message authentication mechanism;
Due to the lack of UI components, it is realistic to say that the cost of accessing new users may be slightly higher, but as the business scale expands and product demand increases, I believe everyone will like LeanCloud's free and flexible user experience and stable and fast service quality.
The above is the entire content of this article, I hope you like it.
Please take some time to share the article with your friends or leave a comment. We will sincerely thank you for your support!