Advertisement
pedrohcdo

Untitled

Jul 24th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 23.12 KB | None | 0 0
  1. package com.ecv.socketexample.socket;
  2.  
  3. import android.app.Service;
  4. import android.content.Intent;
  5. import android.os.Binder;
  6. import android.os.Handler;
  7. import android.os.HandlerThread;
  8. import android.os.IBinder;
  9. import android.util.Log;
  10.  
  11. import org.json.JSONException;
  12. import org.json.JSONObject;
  13.  
  14. import java.io.BufferedReader;
  15. import java.io.InputStreamReader;
  16. import java.io.PrintWriter;
  17. import java.net.InetSocketAddress;
  18. import java.net.Socket;
  19. import java.net.SocketAddress;
  20. import java.util.Iterator;
  21. import java.util.concurrent.ConcurrentLinkedQueue;
  22.  
  23. /**
  24.  * Created by pedro on 16/07/17.
  25.  */
  26.  
  27. public class ConnectionService extends Service {
  28.  
  29.     /**
  30.      * Binder
  31.      */
  32.     public class ConnectionBinder extends Binder {
  33.  
  34.         /**
  35.          * Get Service
  36.          * @return
  37.          */
  38.         public ConnectionService getService() {
  39.             return ConnectionService.this;
  40.         }
  41.     }
  42.  
  43.     /**
  44.      * Request Result
  45.      *
  46.      */
  47.     public interface RequestResult {
  48.  
  49.         /** On result */
  50.         public void onResult(int result, String message);
  51.     }
  52.  
  53.     /**
  54.      * Socket Listener
  55.      */
  56.     public interface SocketListener {
  57.  
  58.         /**
  59.          * On Disconnected
  60.          */
  61.         public void onDisconnected();
  62.  
  63.         /**
  64.          * On Received Data
  65.          *
  66.          * @param data
  67.          */
  68.         public void onReceivedData(String data);
  69.     }
  70.  
  71.     /**
  72.      * Message
  73.      */
  74.     public class Message {
  75.  
  76.         //
  77.         int control;
  78.         String message;
  79.         long dispatchTime;
  80.  
  81.         /**
  82.          * Constructor
  83.          *
  84.          * @param message
  85.          * @param dispatchTime
  86.          */
  87.         public Message(final int control, final String message, final long dispatchTime) {
  88.             this.control = control;
  89.             this.message = message;
  90.             this.dispatchTime = dispatchTime;
  91.         }
  92.     }
  93.  
  94.     //
  95.     ConnectionBinder mBinder = new ConnectionBinder();
  96.     Socket mClientSocket = null;
  97.     volatile int mLoginControl = 0; /* To invalidate invalid connections */
  98.     Handler mHandler;
  99.     volatile SocketListener mSocketListener;
  100.     volatile boolean mConnected = false;
  101.  
  102.     //
  103.     private BufferedReader in = null;
  104.     private PrintWriter out = null;
  105.     private volatile long mPingAlarmClock = 0;
  106.  
  107.     //
  108.     final private ConcurrentLinkedQueue<Message> mMessages = new ConcurrentLinkedQueue<>();
  109.  
  110.     /**
  111.      * On bind
  112.      * @param intent
  113.      * @return
  114.      */
  115.     @Override
  116.     public IBinder onBind(Intent intent) {
  117.         return mBinder;
  118.     }
  119.  
  120.     /**
  121.      * On created
  122.      */
  123.     @Override
  124.     public void onCreate() {
  125.         super.onCreate();
  126.         Log.d("LogTest", "Created service");
  127.         //
  128.         HandlerThread thread = new HandlerThread("ConnectionHT", android.os.Process.THREAD_PRIORITY_BACKGROUND);
  129.         thread.start();
  130.         mHandler = new Handler(thread.getLooper());
  131.     }
  132.  
  133.     /**
  134.      * Call runnable
  135.      *
  136.      * @param control
  137.      * @param runnable
  138.      */
  139.     public void callRunnable(final int control, final Runnable runnable) {
  140.         /**
  141.          * Post result to ui thread
  142.          */
  143.         mHandler.post(new Runnable() {
  144.             @Override
  145.             public void run() {
  146.                 if(mLoginControl == control)
  147.                     runnable.run();
  148.             }
  149.         });
  150.     }
  151.  
  152.     /**
  153.      * Dispatch Message
  154.      *
  155.      * @param message
  156.      * @param delayed
  157.      */
  158.     private void dispatchMessage(final String message, final int delayed, final int control) {
  159.         // Prevent invalid messages
  160.         if(control == mLoginControl)
  161.           mMessages.add(new Message(control, message, System.currentTimeMillis() + delayed));
  162.     }
  163.  
  164.     /**
  165.      * Dispatch Message
  166.      *
  167.      * @param message
  168.      */
  169.     private void dispatchMessage(final String message, final int control) {
  170.         // Prevent invalid messages
  171.         if(control == mLoginControl)
  172.             mMessages.add(new Message(control, message, System.currentTimeMillis()));
  173.     }
  174.  
  175.     /**
  176.      * Dispatch Message
  177.      *
  178.      * @param message
  179.      * @param delayed
  180.      */
  181.     public void sendMessage(final String message, final int delayed) {
  182.         if(isConnected())
  183.             mMessages.add(new Message(mLoginControl, message, System.currentTimeMillis() + delayed));
  184.     }
  185.  
  186.     /**
  187.      * Dispatch Message
  188.      *
  189.      * @param message
  190.      */
  191.     public void sendMessage(final String message) {
  192.         if(isConnected())
  193.             mMessages.add(new Message(mLoginControl, message, System.currentTimeMillis()));
  194.     }
  195.  
  196.     /**
  197.      * Ping Socket
  198.      */
  199.     private void pingSocket(final int control, final int delay) {
  200.         // Heartbeat JSON
  201.         final JSONObject heartbeatJson = new JSONObject();
  202.         try {
  203.             heartbeatJson.put("action", "ping");
  204.         } catch (Exception e) {
  205.             Log.d("LogTest", "Error on make json.");
  206.         }
  207.         //
  208.         Log.d("LogTest", "Dispatched ping in control " + control + " of " + mLoginControl);
  209.         dispatchMessage(heartbeatJson.toString(), delay, control);
  210.         // Set Alarm
  211.  
  212.         mPingAlarmClock = System.currentTimeMillis() + ConnectUtils.HEARTBEAT_ALARM_CLOCK;
  213.         Log.d("LogTest", "Set alarm (" + mPingAlarmClock + ") in control " + control + " of " + mLoginControl);
  214.         //
  215.         final long setPing = mPingAlarmClock;
  216.         // Set Alarm Checker
  217.         mHandler.postDelayed(new Runnable() {
  218.             @Override
  219.             public void run() {
  220.                 if(mLoginControl == control && mPingAlarmClock <= setPing) {
  221.                     Log.d("LogTest", "Dont received pong (" + mPingAlarmClock + ", " + System.currentTimeMillis() + ") in control " + control + " of " + mLoginControl);
  222.                     if(mSocketListener != null)
  223.                         mSocketListener.onDisconnected();
  224.                 }
  225.             }
  226.         }, ConnectUtils.HEARTBEAT_ALARM_CLOCK + 100);
  227.     }
  228.  
  229.     /**
  230.      * Start Receiver Thread
  231.      */
  232.     public void startSocketControlThread(final BufferedReader in, final PrintWriter out, final int control) {
  233.         //
  234.         new Thread(new Runnable() {
  235.  
  236.             /**
  237.              * Run
  238.              */
  239.             @Override
  240.             public void run() {
  241.                 // First Heartbeat
  242.                 Log.d("LogTest", "Socket control(" + control + ") created");
  243.                 Log.d("LogTest", "First ping");
  244.                 pingSocket(control, 0);
  245.                 //
  246.                 while(true) {
  247.                     //
  248.                     //
  249.                     if(mLoginControl != control) {
  250.                         Log.d("LogTest", "SocketControl(receive)(" + mLoginControl + ") is dead");
  251.                         break;
  252.                     }
  253.                     //
  254.                     try {
  255.                         // This if is to read if have mReceiver
  256.                         if(mSocketListener != null) {
  257.                             String data = ConnectUtils.readText(in, 10000);
  258.                             Log.d("LogTest", "Received data: " + data);
  259.                             // This if is to prevent read delay
  260.                             if(mSocketListener != null && mLoginControl == control) {
  261.                                 boolean consumed = false;
  262.                                 try {
  263.                                     JSONObject receivedJson = new JSONObject(data);
  264.                                     if(!receivedJson.isNull("messageType")) {
  265.                                         final String type = receivedJson.getString("messageType");
  266.                                         if (type.equals("pong")) {
  267.                                             Log.d("LogTest", "Received pong.");
  268.                                             pingSocket(control, ConnectUtils.HEARTBEAT_TIME);
  269.                                             consumed = true;
  270.                                         }
  271.                                     }
  272.                                 } catch (Exception e) {}
  273.                                 if(!consumed) {
  274.                                     mSocketListener.onReceivedData(data);
  275.                                 } else {
  276.                                     Log.d("LogTest", "Consumed message " + data + " from server.");
  277.                                 }
  278.                             }
  279.                         }
  280.                     } catch (Exception e) {
  281.                         Log.d("LogTest", "Error in control " + control + " of " + mLoginControl + ". " + e.getMessage());
  282.                     }
  283.  
  284.                     //
  285.                     try {
  286.                         Thread.sleep(10);
  287.                     } catch (Exception e) {
  288.                         Log.d("LogTest", "Socket control dead in control " + control + " of " + mLoginControl + ". Error: " + e.getMessage());
  289.                         // If error on sleep break this while(true){..}
  290.                         break;
  291.                     }
  292.                 }
  293.             }
  294.         }).start();
  295.  
  296.         //
  297.         //
  298.         new Thread(new Runnable() {
  299.  
  300.             /**
  301.              * Run
  302.              */
  303.             @Override
  304.             public void run() {
  305.                 // First Heartbeat
  306.                 Log.d("LogTest", "Socket control(" + control + ") created");
  307.                 Log.d("LogTest", "First ping");
  308.                 pingSocket(control, 0);
  309.                 //
  310.                 while(true) {
  311.                     //
  312.                     //
  313.                     if(mLoginControl != control) {
  314.                         Log.d("LogTest", "SocketControl(Receive)(" + mLoginControl + ") is dead");
  315.                         break;
  316.                     }
  317.                     //
  318.                     try {
  319.                         // Dispatch messages
  320.                         while(mMessages.size() > 0) {
  321.                             Iterator<Message> itr = mMessages.iterator();
  322.                             while(itr.hasNext()) {
  323.                                 final Message m = itr.next();
  324.                                 if(mLoginControl == m.control && System.currentTimeMillis() > m.dispatchTime) {
  325.                                     out.println(m.message);
  326.                                     out.flush();
  327.                                     itr.remove();
  328.                                     //
  329.                                     Log.d("LogTest", "Dispatched message to server " + m.message);
  330.                                 }
  331.                             }
  332.                         }
  333.                     } catch (Exception e) {
  334.                         Log.d("LogTest", "Error in control " + control + " of " + mLoginControl + ". " + e.getMessage());
  335.                     }
  336.  
  337.                     //
  338.                     try {
  339.                         Thread.sleep(10);
  340.                     } catch (Exception e) {
  341.                         Log.d("LogTest", "Socket control dead in control " + control + " of " + mLoginControl + ". Error: " + e.getMessage());
  342.                         // If error on sleep break this while(true){..}
  343.                         break;
  344.                     }
  345.                 }
  346.             }
  347.         }).start();
  348.     }
  349.  
  350.     /**
  351.      * It starts the login process, if this function is called twice or more times overlapping
  352.      * login processes that were in progress, it is prepared to ignore the previous results using
  353.      * the login control.
  354.      *
  355.      * @param accountNumber
  356.      * @param imei
  357.      * @param password
  358.      */
  359.     public void startLogin(final String accountNumber, final String imei, final String password, final RequestResult runnable) {
  360.         /** Invalidate others logins (if have) */
  361.         logout();
  362.         final int control = mLoginControl;
  363.  
  364.         /** Start new login thread */
  365.         new Thread(new Runnable() {
  366.  
  367.             /**
  368.              * Run
  369.              */
  370.             @Override
  371.             public void run() {
  372.                 try {
  373.                     Log.d("LogTest", "Created address");
  374.                     SocketAddress socketAddress = new InetSocketAddress(ConnectUtils.HOST, ConnectUtils.POST);
  375.                     final Socket socket = new Socket();
  376.                     Log.d("LogTest", "Start connecting");
  377.                     socket.connect(socketAddress, 10000);
  378.                     Log.d("LogTest", "End connecting");
  379.  
  380.                     //
  381.                     if(socket.isConnected()) {
  382.                         Log.d("LogTest", "A");
  383.  
  384.                         in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
  385.                         out = new PrintWriter(socket.getOutputStream());
  386.  
  387.  
  388.                         Log.d("LogTest", "B");
  389.                         //
  390.                         JSONObject json = new JSONObject();
  391.                         json.put("action", "login");
  392.                         json.put("language", "zh_CN");
  393.                         json.put("accountNumber", accountNumber);
  394.                         json.put("imei", imei);
  395.                         json.put("password", password);
  396.  
  397.                         Log.d("LogTest", "C: " + json.toString());
  398.                         // Start login
  399.                         out.println(json.toString());
  400.                         out.flush();
  401.  
  402.                         Log.d("LogTest", "D");
  403.                         // Wait 20s
  404.                         final String received = ConnectUtils.readText(in, 100000);
  405.                         Log.d("LogTest", "E");
  406.                         //
  407.                         try {
  408.                             //
  409.                             Log.d("LogTest", "Received: " + received);
  410.  
  411.                             final JSONObject receivedJson = new JSONObject(received);
  412.                             Log.d("LogTest", "F");
  413.                             String flag = receivedJson.getString("flag");
  414.  
  415.                             if(flag.trim().equals("00")) {
  416.                                 //
  417.                                 callRunnable(control, new Runnable() {
  418.                                     @Override
  419.                                     public void run() {
  420.                                         mConnected = true;
  421.                                         mClientSocket = socket;
  422.                                         // Start receiver thread
  423.                                         startSocketControlThread(in, out, control);
  424.                                         // Ok
  425.                                         runnable.onResult(1, "Just here, okay: " + receivedJson);
  426.                                     }
  427.                                 });
  428.                             } else {
  429.                                 //
  430.                                 callRunnable(control, new Runnable() {
  431.                                     @Override
  432.                                     public void run() {
  433.                                         mConnected = false;
  434.                                         mClientSocket = null;
  435.                                         runnable.onResult(-1, "Wrong loging account: " + receivedJson);
  436.                                     }
  437.                                 });
  438.                             }
  439.                         } catch (JSONException jsonE) {
  440.                             Log.d("LogTest", "Error: " + jsonE);
  441.  
  442.                             callRunnable(control, new Runnable() {
  443.                                 @Override
  444.                                 public void run() {
  445.                                     runnable.onResult(-1, "Could not recognize data received after login: " + received);
  446.                                 }
  447.                             });
  448.                         }
  449.                         Log.d("LogTest", "G");
  450.                     } else {
  451.                         callRunnable(control, new Runnable() {
  452.                             @Override
  453.                             public void run() {
  454.                                 runnable.onResult(-1, "Could not connect to socket.");
  455.                             }
  456.                         });
  457.                     }
  458.  
  459.  
  460.                     //
  461.                 } catch (final Exception e) {
  462.                     callRunnable(control, new Runnable() {
  463.                         @Override
  464.                         public void run() {
  465.                             runnable.onResult(-1, "Error on connect (" + accountNumber + ", " + imei + ", " + password + ") with control " + control + " and global control " + mLoginControl + ". Error: " + e.getMessage());
  466.                         }
  467.                     });
  468.                 }
  469.             }
  470.         }).start();
  471.     }
  472.  
  473.     /**
  474.      * It starts the reconnection process, if this function is called twice or more times overlapping
  475.      * login processes that were in progress, it is prepared to ignore the previous results using
  476.      * the login control.
  477.      *
  478.      * @param accountNumber
  479.      * @param imei
  480.      * @param password
  481.      */
  482.     public void startReconnection(final String accountNumber, final String imei, final String password, final RequestResult runnable) {
  483.         /** Invalidate others logins (if have) */
  484.         logout();
  485.         final int control = mLoginControl;
  486.         /** Start new login thread */
  487.         new Thread(new Runnable() {
  488.  
  489.             /**
  490.              * Run
  491.              */
  492.             @Override
  493.             public void run() {
  494.                 try {
  495.                     Log.d("LogTest", "Created address");
  496.                     SocketAddress socketAddress = new InetSocketAddress(ConnectUtils.HOST, ConnectUtils.POST);
  497.                     final Socket socket = new Socket();
  498.                     Log.d("LogTest", "Start connecting");
  499.                     socket.connect(socketAddress, 10000);
  500.                     Log.d("LogTest", "End connecting");
  501.  
  502.                     //
  503.                     if(socket.isConnected()) {
  504.                         Log.d("LogTest", "A");
  505.  
  506.                         in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
  507.                         out = new PrintWriter(socket.getOutputStream());
  508.  
  509.  
  510.                         Log.d("LogTest", "B");
  511.                         //
  512.                         JSONObject json = new JSONObject();
  513.                         json.put("action", "reconnect");
  514.                         json.put("language", "zh_CN");
  515.                         json.put("accountNumber", accountNumber);
  516.                         json.put("imei", imei);
  517.                         json.put("password", password);
  518.  
  519.                         Log.d("LogTest", "C: " + json.toString());
  520.                         // Start login
  521.                         out.println(json.toString());
  522.                         out.flush();
  523.  
  524.                         Log.d("LogTest", "D");
  525.                         // Wait 20s
  526.                         final String received = ConnectUtils.readText(in, 100000);
  527.                         Log.d("LogTest", "E");
  528.                         //
  529.                         try {
  530.                             //
  531.                             Log.d("LogTest", "Received: " + received);
  532.  
  533.                             final JSONObject receivedJson = new JSONObject(received);
  534.                             Log.d("LogTest", "F");
  535.                             String flag = receivedJson.getString("flag");
  536.                             Log.d("LogTest", "Get flag: " + flag);
  537.                             if(flag.trim().equals("00")) {
  538.                                 Log.d("LogTest", "Reconnected");
  539.                                 //
  540.                                 callRunnable(control, new Runnable() {
  541.                                     @Override
  542.                                     public void run() {
  543.                                         mConnected = true;
  544.                                         mClientSocket = socket;
  545.                                         Log.d("LogTest", "Saved Socket and start socket controller");
  546.                                         // Start receiver thread
  547.                                         startSocketControlThread(in, out, control);
  548.                                         Log.d("LogTest", "Just here okay");
  549.                                         // Ok
  550.                                         runnable.onResult(1, "Just here, okay: " + receivedJson);
  551.                                     }
  552.                                 });
  553.                             } else {
  554.                                 Log.d("LogTest", "Error on reconnect");
  555.                                 //
  556.                                 callRunnable(control, new Runnable() {
  557.                                     @Override
  558.                                     public void run() {
  559.                                         mConnected = false;
  560.                                         mClientSocket = null;
  561.                                         runnable.onResult(-2, "Wrong loging account: " + receivedJson);
  562.                                     }
  563.                                 });
  564.                             }
  565.                         } catch (JSONException jsonE) {
  566.                             Log.d("LogTest", "Error: " + jsonE);
  567.  
  568.                             callRunnable(control, new Runnable() {
  569.                                 @Override
  570.                                 public void run() {
  571.                                     runnable.onResult(-1, "Could not recognize data received after login: " + received);
  572.                                 }
  573.                             });
  574.                         }
  575.                         Log.d("LogTest", "G");
  576.                     } else {
  577.                         Log.d("LogTest", "Socket dont connected");
  578.                         callRunnable(control, new Runnable() {
  579.                             @Override
  580.                             public void run() {
  581.                                 runnable.onResult(-1, "Could not connect to socket.");
  582.                             }
  583.                         });
  584.                     }
  585.  
  586.  
  587.                     //
  588.                 } catch (final Exception e) {
  589.                     Log.d("LogTest", "Error on connect (: " + e.getMessage());
  590.                     callRunnable(control, new Runnable() {
  591.                         @Override
  592.                         public void run() {
  593.                             runnable.onResult(-1, "Error on connect (" + accountNumber + ", " + imei + ", " + password + ") with control " + control + " and global control " + mLoginControl + ". Error: " + e.getMessage());
  594.                         }
  595.                     });
  596.                 }
  597.             }
  598.         }).start();
  599.     }
  600.  
  601.     /**
  602.      * Logout
  603.      */
  604.     public void logout() {
  605.         mLoginControl++;
  606.         mClientSocket = null;
  607.         mConnected = false;
  608.         mMessages.clear();
  609.         mPingAlarmClock = 0;
  610.         in = null;
  611.         out = null;
  612.     }
  613.  
  614.     /**
  615.      * Is connected
  616.      *
  617.      * @return
  618.      */
  619.     public boolean isConnected() {
  620.         return mConnected && mClientSocket != null;
  621.     }
  622.  
  623.     /**
  624.      * Set Receiver
  625.      *
  626.      * @param listener
  627.      */
  628.     public void setSocketListener(final SocketListener listener) {
  629.         mSocketListener = listener;
  630.     }
  631. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement