The polling request service of the game system source code, in general, often acts on the request server. For example, on a certain page, we have a scheduled task to obtain and display the updated information from the server from time to time. For example, after the long connection is broken, we may need to start a polling request as a supplement to the long connection. Therefore, the polling service is used in the source code of the game system.
What is a polling request?
Before we explain the polling request, let's first explain what is called polling request. My understanding is that the operation of the source code of the accompanying game system to repeat the request every certain time is called polling request. For example, the source code of the accompanying game system reports the positioning information every other period of time, and the source code of the accompanying game system pulls the user status every other period of time, These should be polling requests.
Polling request practice
Polling requests related to long connections
The long connection of the source code of the accompanying game system may be broken. At this time, when the long connection is broken, we need to start a polling service as a supplement to the long connection.
/** * Start polling service */ public void startLoopService() { // Start polling service // Temporarily do not consider the judgment of joining the network if (!LoopService.isServiceRuning) { // When the user is logged in, start the polling service if (UserConfig.isPassLogined()) { // Judge the status of the current long connection. If the long connection is connected, the polling service will not be started if (MinaLongConnectManager.session != null && MinaLongConnectManager.session.isConnected()) { LoopService.quitLoopService(context); return; } LoopService.startLoopService(context); } else { LoopService.quitLoopService(context); } } }
Here is the source code of the accompanying game system to execute the operation code of the polling service. Its function is to start a polling service (i.e. polling service) and then execute specific polling requests in the polling service. In this case, let's take a look at the code logic of this service.
Polling service requests related to long connections
/** * Start the service when the long connection is abnormal, and close the service when the long connection is restored */ public class LoopService extends Service { public static final String ACTION = "com.youyou.uuelectric.renter.Service.LoopService"; /** * The time interval at which the client performs polling. This value is returned by the StartQueryInterface interface. The default setting is 30s */ public static int LOOP_INTERVAL_SECS = 30; /** * Polling interval (the MLOOP_INTERVAL_SECS interval variable is issued by the server. At this time, the scenario and logic of the polling service change during definition, involving the IOS end. Therefore, the self-defined constant is used to write the dead time interval on the client) */ public static int MLOOP_INTERVAL_SECS = 30; /** * Is the current service executing */ public static boolean isServiceRuning = false; /** * Scheduled task tool class */ public static Timer timer = new Timer(); private static Context context; public LoopService() { isServiceRuning = false; } //-------------------------------Polling service using alarm clock------------------------------------ /** * Start polling service */ public static void startLoopService(Context context) { if (context == null) return; quitLoopService(context); L.i("Enable polling service, polling interval:" + MLOOP_INTERVAL_SECS + "s"); AlarmManager manager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context.getApplicationContext(), LoopService.class); intent.setAction(LoopService.ACTION); PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); // long triggerAtTime = SystemClock.elapsedRealtime() + 1000; /** * The first execution time of the alarm clock, in milliseconds. You can customize the time, but generally use the current time. It should be noted that this attribute is closely related to the first attribute (type), * If the alarm clock corresponding to the first parameter uses relative time (ELAPSED_REALTIME and ELAPSED_REALTIME_WAKEUP), this attribute must use relative time (relative to system startup time), * For example, the current time is expressed as: systemclock elapsedRealtime(); * If the alarm clock corresponding to the first parameter uses absolute time (RTC, RTC_WAKEUP, POWER_OFF_WAKEUP), this attribute must use absolute time, * For example, the current time is represented by system currentTimeMillis(). */ manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), MLOOP_INTERVAL_SECS * 1000, pendingIntent); } /** * Stop polling service */ public static void quitLoopService(Context context) { if (context == null) return; L.i("Turn off polling alarm service..."); AlarmManager manager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context.getApplicationContext(), LoopService.class); intent.setAction(LoopService.ACTION); PendingIntent pendingIntent = PendingIntent.getService(context.getApplicationContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); manager.cancel(pendingIntent); // Turn off polling service L.i("Turn off polling service..."); context.stopService(intent); } @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { L.i("Start polling service... \n Judge whether the current user has logged in..."); // If the current network is abnormal or the user is not logged in, it will not jump if (UserConfig.isPassLogined()) { // Judge the current long connection status. If the long connection is normal, turn off the polling service L.i("The current user is logged in... \n Determine whether the long connection has been connected..."); if (MinaLongConnectManager.session != null && MinaLongConnectManager.session.isConnected()) { L.i("Long connection resumed, exit polling service..."); quitLoopService(context); } else { if (isServiceRuning) { return START_STICKY; } // Start polling pull message startLoop(); } } else { L.i("The user has logged out and turned off the polling service..."); quitLoopService(context); } return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); L.i("Polling service exit, execute onDestory()method, inServiceRuning assignment false"); isServiceRuning = false; timer.cancel(); timer = new Timer(); } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } /** * Start polling pull message */ private void startLoop() { if (timer == null) { timer = new Timer(); } timer.schedule(new TimerTask() { @Override public void run() { isServiceRuning = true; L.i("The long connection is not restored. Perform the polling operation... \n Request in polling service getInstance Interface..."); LoopRequest.getInstance(context).sendLoopRequest(); } }, 0, MLOOP_INTERVAL_SECS * 1000); } }
It can be found that there is still a large amount of code for the service polling service here, but the comments on the polling service request code have been very detailed, so I won't explain it too much. It should be noted that its core is to let the game system source code execute the network request once a period of time through the Timer object.
Specific network request code:
L.i("The long connection is not restored. Perform the polling operation... \n Request in polling service getInstance Interface..."); LoopRequest.getInstance(context).sendLoopRequest();
The core logic of the polling service request here: when the long connection is abnormal, start the source code polling service of the game system, pull the server state every certain time through the Timer object, and close the polling service when the long connection is restored. This is the code execution logic of our polling service related to long connections.
Page related polling requests
In the source code of the accompanying game system, when the user stays on a page, we may need to pull the user status regularly. At this time, we also need to use the polling request to pull the server status. When the user leaves the page, we need to close the polling service request.
Let's take a look at the execution logic of this timing request:
/** * TimerTask Object, which is mainly used to pull server information regularly */ public class Task extends TimerTask { @Override public void run() { L.i("Start execution timer Timed task..."); handler.post(new Runnable() { @Override public void run() { isFirstGetData = false; getData(true); } }); } }
The getData method here is to pull the server status. There is no explanation here. When the user exits this page, the polling operation here needs to be cleared. Therefore, clearing timerTask is performed in the ondescriptoryview method of Fragment.
@Override public void onDestroyView() { super.onDestroyView(); ... if (timer != null) { timer.cancel(); timer = null; } if (timerTask != null) { timerTask.cancel(); timerTask = null; } ... }
In this way, when the user opens this page, the TimerTask object is initialized. The source code of the accompanying game system will request the server to pull relevant information and update the UI every minute. When the user leaves the page, the TimerTask object is cleared, that is, the polling request operation is cancelled. It can be found that the polling request services related to long connections and pages we saw above are all polling request services implemented through the timer object's timing task.
Let's take a look at how to implement the polling request service through the Handler object.
Implement the polling request through the Handler object
Let's look at a polling request service implemented through Handler asynchronous messages.
/** * Default interval: 1 minute */ private static int DEFAULT_INTERVAL = 60 * 1000; /** * Polling interval under abnormal conditions: 5 seconds */ private static int ERROR_INTERVAL = 5 * 1000; /** * The time interval at which the current poll is executed */ private static int interval = DEFAULT_INTERVAL; /** * Message type of polling Handler */ private static int LOOP_WHAT = 10; /** * Is this the first time to pull data */ private boolean isFirstRequest = false; /** * Is the first data request successful */ private boolean isFirstRequestSuccess = false; /** * Start polling. Normally, poll and pull the latest data every 1 minute * Enable polling on onStart */ private void startLoop() { L.i("page onStart,Polling needs to be turned on"); loopRequestHandler.sendEmptyMessageDelayed(LOOP_WHAT, interval); } /** * Turn off polling and stop the polling operation when onStop is displayed on the interface */ private void stopLoop() { L.i("Page already onStop,Polling needs to be stopped"); loopRequestHandler.removeMessages(LOOP_WHAT); } /** * Handler handling polling */ private Handler loopRequestHandler = new Handler() { @Override public void handleMessage(Message msg) { // If the first request fails, if (!isFirstRequestSuccess) { L.i("The first request failed. You need to set the polling time to:" + ERROR_INTERVAL); interval = ERROR_INTERVAL; } else { interval = DEFAULT_INTERVAL; } L.i("Polling-----Current polling interval:" + interval); loopRequestHandler.removeMessages(LOOP_WHAT); // When the first request is successful or the location is unsuccessful, perform relocation and load node data if (!isFirstRequestSuccess || !Config.locationIsSuccess()) { isClickLocationButton = false; doLocationOption(); } else { loadData(); } System.gc(); loopRequestHandler.sendEmptyMessageDelayed(LOOP_WHAT, interval); } };
Here is the polling operation realized by the handler. Its core principle is that in the handler's handlerMessage method, the source code of the game system sends the delay message again after receiving the message. The delay time here is the polling interval defined by us, so that we can send the delay message again when we receive the message next time, This leads to the situation that we send polling messages from time to time.
The above are the two ways to realize polling operation in the source code of the game system:
- The Timer object implements polling operations
- The Handler object implements polling operations
Above, we have analyzed different usage scenarios, functions and implementation methods of polling requests. When we need to regularly pull messages from the server in the specific development process of the source code of the game system, we can consider using polling requests.
Summary:
Generally, the polling operation is to request the server to pull the information and update the UI regularly;
Polling operations generally have a certain life cycle, such as starting the polling operation when a page of the game system source code is opened, and canceling the polling operation when a page is closed;
The request interval of polling operation shall be determined according to the specific requirements of the game system source code, and the interval shall not be too short, otherwise it may cause concurrency problems;
In the process of source code development of the accompanying game system, when some users need to try to update the server to pull information and update the UI, they can consider using polling operation;
The polling request operation can be realized through Timer object and Handler object;