Introduction
Message Queue Telemetry Transport (MQTT) is an instant communication protocol based on the publish-subscribe pattern. It is lightweight, open source, easy-to-use, and supports Quality of Service (QOS). These features, along with its low energy consumption, make MQTT suitable for applications such as the Internet of Things (IoT) and mobile Internet.
IBM Message Queue (MQ) provides support to MQTT protocol and is fully compatible with the MQTT standard protocol. When comparing MQTT with standard protocol during usage, the following two points highlighted:
1. Creating the Parent Topic in Advance
Multiple levels of dynamic topics exist in the typical MQTT protocol, which eliminates the need to define and create them in advance. MQ topics are set up in advance in the MQ Console because MQTT is queue-oriented (for message persistence). MQ supports not only the MQTT protocol but also Transmission Control Protocol (TCP) and Hypertext Transfer Protocol (HTTP). To ensure intercommunication between messages of different access methods, MQTT provides the following adaptations:
- Defines the first level of the topic as parent topic.
- Creates parent topic in the MQ Console before using MQ.
- No need to create child topics.
- Child topics used directly in code.
2. Supporting Peer-to-Peer (P2P) Without Showing Subscribers
P2P serves as a supplement to the standard MQTT protocol, which does not support P2P. All clients connected through the TCP/HTTP protocols can receive or send P2P messages.
The dynamic MQTT topics allow ample space for designers, but be sure to give careful attention to the following points:
- Do not include "/" and spaces in the name.
- Keep topics short and concise.
- Use UTF-8 encoding to avoid unreadable characters.
- Consider embedding the unique device number into the topic in specific scenarios to facilitate identification of message senders. For example, only client1 is allowed to publish messages to client1/status and not to client2/status. When you receive messages from client1/status, you can be sure that client1 sent the message.
- Use the wildcard character "#" with caution. For example, if you subscribe to news/sport/#, you will receive all messages from news/sport, such as news/sport/player1, news/sport/player2, and news/sport/player1/score. This can overload the receiving terminal (mobile terminal or embedded device).
- Scalable - The subscription relationship should be created first so the sender and receiver can understand the existence of topics in advance. An intelligent topic structure design allows for the addition of only child topics when a new business demand emerges, without changing the parent topics or overthrowing the original topic structure.
For example, you can design the news about Li Na in the news/lina structure. However, there could be other people named Li Na in the cultural, sports, and entertainment circles. If users want to subscribe to news about Li Na specifically in the tennis circle, the topic structure has to be changed. The suggested designs below will produce better results:
news/sport/tennis/lina
news/sport/tennis/lina/ranking
news/sport/tennis/lina/score/australianopen
Implementation of Social IM with MQTT
Listed below are few scenarios about the implementation of social IM with MQTT:
Preparations: Create parent topics and Group ID in the MQ Console
A Client ID is required for every device to connect to the MQTT service. The Client ID is the client's unique identifier and should be globally unique.
The Client ID is composed of two parts:
- Group ID: The Group ID is applied and created in the MQ Console. It is used to specify the name of a group of nodes with the same logic and functions, representing a category of devices with the same tasks.
- Device ID: The Device ID is the unique identifier of every device. The business entity specifies the Device ID, and you do not need to create it in the MQ Console.
We will create the parent topic IMS in the MQ Console and the GroupID of GID_IMS. We will assume the following for Device IDs:
- User A uses device GID_IMS@@@DeviceID_A
- User B uses device GID_IMS@@@DeviceID_B
- User C uses device GID_IMS@@@DeviceID_C
Scenario 1: User A requests to add User B as a friend for one-to-one chat
Solution 1: Use P2P messaging
The advantage to P2P messaging is that both sides do not need to subscribe in advance. The disadvantage is that if DeviceID_B receives a friend request from multiple users at the same time, it is difficult to identify the sender of each request.
The identification is unavailable from the message topic. We can parse the message body to identify the sender.
Note: In P2P messaging, the secondary topic must contain the P2P text, and the tertiary topic is the target device's Client ID.
Solution 2: Design an inbox for every user and every user should subscribe to his/her inbox via the client login.
The advantage of this solution is that every user can parse the topic to know the sender of each incoming friend request and find out who has accepted the friend request.
When User B receives the message IMS/UserB/Inbox/Add/GFReq/UserA, User B knows User A sent the friend request.
When User A receives the message IMS/UserA/Inbox/Add/GFResp/UserB, User A knows it is User B's feedback.
Scenario 2: User A follows User B's updates and receives updates when User B updates his profile
To follow User B's updates, User A subscribes to IMS/UserB. When User B shares content, User B publishes it to IMS/UserB. Subscribers (i.e., friends) of IMS/UserB can view the post (MQTT is responsible for sending the message to all subscribers).
If User A does not want to see User B's profile updates, User A can cancel the subscription to IMS/UserB.
What if User B does not want User A to see User B's shared messages?
An inbox is also an option in this scenario. User A subscribes to IMS/UserA/Inbox/Update/# at login. User B sends a message to IMS/UserA/Inbox/Update/UserB/Unsub. After User A receives this message, User A cancels the subscription to IMS/UserB. User A will no longer see User B's Moments updates.
After User A receives User B's subscription cancellation request, it is the application designer's responsibility to determine whether to display a prompt box notifying User A (User B blacklists User A) or have it done silently (User B silently blacklists User A).
Scenario 3: User A invites User B and User C to join a group chat. User B and User C are not friends. Both are friends with User A.
First, the group chat initiator, User A, subscribes to IMS/Group123/#. P2P messaging is used to invite User B and User C to join the group chat.
User B and User C subscribe to IMS/Group123/# to agree to join the conversation. User B can publish to IMS/Group123/UserB with User B's identity information in the group chat if User B wants to send a message to the group. This allows all members subscribed to IMS/Group123/# to see User B's message.
Scenario 4: Send messages to a group of friends at holidays (not group chat)
You can send P2P messages to friends one by one or send messages to your friend's inboxes. The disadvantage is you need to publish the message multiple times, depending on how many friends you want to receive the message.
Does a solution exist to reduce the effort involved in publishing multiple times?
MQTT intends to create a virtual group to simplify this process. Friends do not need to subscribe to this group explicitly. Instead, the subscription relationship is set up by the system dynamically based on the business configuration. Friends can receive messages sent to this group without noticing the existence of this group because the client did not initiate the action to subscribe to this virtual group (in a similar principle of P2P subscription).
MQTT does not support this feature currently.
Scenario 5: Commercial marketing - the system pushes messages to users in different categories/with different positioning
If you want to send a New Year greeting to users in various regions with the message content varying according to the region, you can use P2P or inbox, as in scenario 4. However, this is not an ideal solution for the entire system since there are many users.
Since MQTT does not support virtual groups currently, how can we implement this function?
During the business design, a topic for system broadcasting is reserved, such as IMS/System. Every user, apart from subscribing to his/her inbox and friends, also subscribes to the system preserved topic based on the user's region (see Figure 7).
For example:
Beijing users are subscribed to IMS/System/Beijing
Hangzhou users are subscribed to IMS/System/Hangzhou
When the system sends a message to IMS/System/Beijing, all Beijing users will receive the message. Similarly, when the system sends a message to IMS/System/Hangzhou, all Hangzhou users will receive the message.
When a user logs into the client, the business application will identify the user's region first and make the user subscribe to the preserved topic of the area. However, this solution is not flexible enough because when the business expands in the future, the program will require updates (subscribe to new topics to meet the new market demand).
Conclusion
MQTT is efficient in scenarios where a small code footprint is needed. It also helps you create an instant messaging app easily and quickly. MQTT is a good solution for wireless networks with flexible latency caused by bandwidth constraints.