Android pushes learning notes for advanced courses and android learning notes
Today, I learned how to process receipt messages on the server side of Android Advanced Course push on MOOC. This course mainly introduces that when the server pushes messages to the client, the client needs to send a receipt to confirm that the push message is received before a complete push process.
The specific implementation method is that when the server pushes a message to the client, a corresponding uuid will be generated to identify the message, and the message and uuid will be stored in the database. After the client receives the message, obtain the uuid and send the uuid to the server. The server receives the uuid and deletes the corresponding message records from the database according to the uuid. The whole push is complete. Here we will first post the core sending code
Public void sendNotifcationToUser (String apiKey, String username, String title, String message, String uri) {log. debug ("sendNotifcationToUser ()... "); Random random = new Random (); // This id is the uuid String id = Integer corresponding to the receipt sent by the client. toHexString (random. nextInt (); IQ notificationIQ = createnotifiq IQ (id, apiKey, title, message, uri); ClientSession session = sessionManager. getSession (username); if (sessio N! = Null) {if (session. getPresence (). isAvailable () {notificationIQ. setTo (session. getAddress (); session. deliver (icationicationiq);} else {saveNotification (apiKey, username, title, message, uri, id) ;}// Save the message to the database regardless of whether the user does not exist, try {User user = mUserService will be deleted after the User receives the message and sends feedback. getUserByUsername (username); if (null! = User) {saveNotification (apiKey, username, title, message, uri, id) ;}} catch (UserNotFoundException e) {// TODO Auto-generated catch block e. printStackTrace ();}}
As you can see, each time a message is pushed to the client, it is checked in.
At the same time, there is also a business logic in the source code. When the server detects that the client is going offline to the online status, it will go to the database to find out whether the customer's message exists, the Code is as follows:
List<Notification> list = mNotificationSevice.findNotificationByUsername(session.getUsername()); if(null != list && list.size() > 0){ for(Notification notification: list){ String apiKey = notification.getApiKey(); String title = notification.getTitle(); String message = notification.getMessage(); String uri = notification.getUri(); mNotificationManager.sendNotifcationToUser(apiKey, session.getUsername(), title, message, uri); mNotificationSevice.deleteNotification(notification); } }
A bug in this Code is that when a message is detected to be sent to a newly launched client, the sendconfigurcationtouser method is called and the original message is deleted from the database, after this operation, you will find that the messages that are stored in sendpoliccationtouser are
MNotificationSevice. deleteNotification (notification); is also deleted (of course, the original incoming messages are also deleted, but this deletion is correct ), the message that has just been written into the database should not be deleted. It must be deleted after the client sends a receipt.
Guo Shen, video author, solves this bug as follows:
Public void sendpoliccationtouser (String apiKey, String username, String title, String message, String uri, boolean shouldSave) {log. debug ("sendNotifcationToUser ()... "); Random random = new Random (); // This id is the uuid String id = Integer corresponding to the receipt sent by the client. toHexString (random. nextInt (); IQ notificationIQ = createnotifiq IQ (id, apiKey, title, message, uri); ClientSession session = sessionManager. getSession (u Sername); if (session! = Null) {if (session. getPresence (). isAvailable () {notificationIQ. setTo (session. getAddress (); session. deliver (icationicationiq);} else {saveNotification (apiKey, username, title, message, uri, id) ;}// Save the message to the database regardless of whether the user does not exist, try {User user = mUserService will be deleted after the User receives the message and sends feedback. getUserByUsername (username); if (null! = User & shouldSave) {saveNotification (apiKey, username, title, message, uri, id) ;}} catch (UserNotFoundException e) {// TODO Auto-generated catch block e. printStackTrace ();}}
The preceding Code adds the shouldSave field to determine whether to import data to the database. When detecting that the client is online and the database has a message that failed to be sent before pushing, the parameter is set to false.
if(null != list && list.size() > 0){ for(Notification notification: list){ String apiKey = notification.getApiKey(); String title = notification.getTitle(); String message = notification.getMessage(); String uri = notification.getUri(); mNotificationManager.sendNotifcationToUser(apiKey, session.getUsername(), title, message, uri, false); mNotificationSevice.deleteNotification(notification); } }
After the test is completed, no problem is found. After the client goes offline to online, the original database messages are lost, meeting the requirements.
However, there is actually a problem. When the client goes offline to online and the server detects a message to be pushed from the database, the last parameter passed into sendconfigurcationtouser is false, there is no warehouse receiving operation at all, so the database does not have the data for sending the message. After the client receives the message delivery receipt, the server does not have the corresponding data to delete, which seems to have achieved the expected results.
To solve this problem, I made the following changes. For the status from offline to online on the client, I need to push the previously pushed message, retrieve the data from the database, and directly push the message, if the message is not deleted or no new message is inserted, the message will be deleted after receiving the receipt from the client.
Public void sendpoliccationtouser (String id, String apiKey, String username, String title, String message, String uri, boolean shouldSave) {log. debug ("sendNotifcationToUser ()... "); IQ notifiq IQ = createnotifiq IQ (id, apiKey, title, message, uri); ClientSession session = sessionManager. getSession (username); if (session! = Null) {if (session. getPresence (). isAvailable () {notificationIQ. setTo (session. getAddress (); session. deliver (icationicationiq);} else if (shouldSave) {saveNotification (apiKey, username, title, message, uri, id );}} // store the message to the database regardless of whether the User exists or not until the user receives the message feedback and then deletes try {User user = mUserService. getUserByUsername (username); if (null! = User & shouldSave) {saveNotification (apiKey, username, title, message, uri, id) ;}} catch (UserNotFoundException e) {// TODO Auto-generated catch block e. printStackTrace ();}}
The id field is added here. Each time a message is sent, the id message generates a new one. For messages before sending, there is no need to generate a new id (uuid ), retrieve the id of the original message, and change the message search location to the following:
List <Notification> list = mNotificationSevice. findNotificationByUsername (session. getUsername (); if (null! = List & list. size ()> 0) {for (Notification notification: list) {String apiKey = notification. getApiKey (); String title = notification. getTitle (); String message = notification. getMessage (); String uri = notification. getUri (); String id = notification. getUuid (); micationicationmanager. sendpoliccationtouser (id, apiKey, session. getUsername (), title, message, uri, false) ;}} to avoid the bug of Guo Shen. In fact, the idea is simple, that is When a new message is sent, It is not stored in the database. Instead, the previous message is taken out for sending and deleted after receiving the receipt from the client.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.