Because I write the article level is not good, the explanation is not good, suggest to download the code to eat together

GitHub

There may be some other things I’m trying to do in there, but it doesn’t affect the framework based on the article

Making portal

Overall frame drawing

Diagram of message beans

The message Bean class may seem hierarchical, but I feel it is cleanly divided and can be extended indefinitely

Message distribution flowchart

A very simple process and design, but the message distribution process is very clear

Enter the code

IMManger message entryHere you can see that after adding IM message listening, the message is delivered directly toIMDispatcher, let him do the message processing.

The handler of the IMDispatcher message first sees some variables defined by IMDispatcher

There’s a List of parsers, an interceptor object, a dispenser factory List

The above variables will be used to parse the message, and the whole call will look like this

  • It first iterates through the parser collection, and whenever it is added to the parser List, it iterates through it until the message is parsed. Why use collections here? Because you might have multiple parsers. Suppose your System messages are split into five large groups of types, and they might parse differently

  • Then to the interceptor, the interceptor is an instance object, and I figured there wouldn’t be too many messages to intercept, so I just made it an instance

  • And then finally the dispenser, just add it to the dispenser factory List, implement the interface method, and you get the message you want, and for the consumer, I don’t care what you did before, I just implement the interface

The practical application

Take the example of passing a custom message

1. Take a look at the base class for custom messages

abstract class BaseCustomMsg<T> : BaseMsgBean() {// When you send a message, it will pass in your Bean, which will be converted to a String stored in this private var param = "" // When you get the message, ParamBean is your current message Bean class @expose (serialize = false) var paramBean: T? = null get() {if (field == null) {val t = typeutils.findNeedType (javaClass) Param already holds the String // of the sender Bean class, so when you get the message, you get the paramBean, and you do the conversion here, Field = typeutils.fromjson <T>(param, T)} return field} private set /** * This method is called with the purpose * 1. */ Open Fun createMsg(paramBean :T){// Create a new data object to pass, val dataObj = JSONObject() dataObj.put("msgAction", Param = typeUtils.tojson (paramBean) // Put value save dataObj. Put ("value", param) val timCustomElem = TIMCustomElem() timCustomElem.data = dataObj.toString().toByteArray() Mtxmessage.addelement (timCustomElem)} /** * */ Override fun addMsgContent(mTxMessage: TIMMessage): BaseMsgBean { val element = mTxMessage.getElement(0) as TIMCustomElem val dataJson = String(element.data) val jsonObject  = JSONObject(dataJson) msgAction = jsonObject.optString("msgAction") param = jsonObject.optString("value") return this }}Copy the code

2. Then if I want to define a Pk request message and need to pass some parameters, then I can define it like this, very simple, and don’t need anything else, just your bean class and give the message an msgAction identifier

class PkReqMsg : BaseCustomMsg<PkReqMsg.PkMsgParam>() {

    data class PkMsgParam(
        var playUrl: String = "",
        var isAgain: Boolean = false,
        var pk_id: String = ""
    )

    override fun getAction() = MsgType.CUSTOM_PK_REQ
}
Copy the code

3. How to send the Pk request message?

  • As you can see, createMsg takes the parameter Bean we want to carry, while createMsg converts the Bean class into a String, assigns a value to Param, and then sends it packaged with msgAction. Take a look back at the base class
Val pkMsgParam = pkreqmsg.pkmsgparam (" PK message ", false, // Call the base class method pkreqmsg.createmsg (pkMsgParam) // send imManager.sendMessage (pkReqMsg)Copy the code

4. So how do you parse the message

  • Parsing messages (note that the TIMElemType type is defined by Tencent itself)
  • Find the corresponding message type according to MsgAction, instantiate newInstance, then call decorateMsg of the base class method, and finally call addMsgContent to get the content

5. How do I get the news?

  • Add, get, remove

6. More simple access, not elaborated here, you can see according to the code

Just fill in the message bean corresponding to msgAction to get the message directly,

Avoid doing all sorts of judgements to transform and get messages in a method like the one above

At the end

This framework is just using Tencent IM as an example, other instant messaging should be able to apply, if you have a better idea of the structure, welcome to add friends to communicate, comment section communication ha, more communication can find deficiencies, can also find their own unexpected level