Socket Behavior Distribution Manager

1. Define the behavior of Socket, SocketAction.java

 /**
   * @Description: Socket behavior
   */
  public interface SocketAction {

      /**
       * connection succeeded
       */
      String ACTION_CONNECT_SUCCESS = "action_connect_success";

      /**
       * Connection failed
       */
      String ACTION_CONNECT_FAIL = "action_connect_fail";

      /**
       * Disconnect
       */
      String ACTION_DISCONNECTION = "action_disconnection";
  }

2. Create Socket action distribution interface, ISocketActionDispatch.java

 /**
   * @Description: Socket behavior distribution interface
   */
  public interface ISocketActionDispatch {

      /**
       * Distribution of Socket behavior
       *
       * @param action
       */
      void dispatchAction(String action);

      /**
       * Distribution of Socket behavior
       *
       * @param action
       * @param serializable
       */
      void dispatchAction(String action, Serializable serializable);

      /**
       * Subscribe to Socket behavior monitoring
       *
       * @param iSocketActionListener
       */
      void subscribe(ISocketActionListener iSocketActionListener);

      /**
       * Unsubscribe from Socket behavior monitoring
       *
       * @param iSocketActionListener
       */
      void unSubscribe(ISocketActionListener iSocketActionListener);


      /**
       * Stop dispatch thread
       *
       * @throws InterruptedException interrupt exception
       */
      void stopDispatchThread() throws InterruptedException;
  }

3. Implement behavior distribution interface, create Socket behavior distributor, SocketActionDispatcher.java

 /**
   * @Description: Socket behavior dispatcher
   */
  public class SocketActionDispatcher implements ISocketActionDispatch {

      /**
       * The host address to connect to
       */
      private SocketAddress socketAddress;


      /**
       * Socket behavior monitoring collection / callback monitoring collection
       */
      private List<ISocketActionListener> actionListeners = new ArrayList<>();

      /**
       * Threads that handle Socket behavior
       */
      private Thread actionThread;

      /**
       * Whether to stop distribution
       */
      private boolean isStop;

      /**
       * Event consumption queue
       */
      private static final LinkedBlockingDeque<ActionBean> actions = new LinkedBlockingDeque<>();

      /**
       * Operate in the UI main thread
       */
      private MainThreadExecutor mainThreadExecutor = new MainThreadExecutor();


      public SocketActionDispatcher(SocketAddress socketAddress) {
          this.socketAddress = socketAddress;
          startDispatchThread();
      }

      //Change the host address
      public void setSocketAddress(SocketAddress socketAddress) {
          this.socketAddress = socketAddress;
      }

      @Override
      public void dispatchAction(String action) {
          dispatchAction(action, null);
      }

      @Override
      public void dispatchAction(String action, Serializable serializable) {
          // Encapsulate the received Socket behavior into the queue
          ActionBean actionBean = new ActionBean(action, serializable, this);
          actions.offer(actionBean);
      }

      @Override
      public void subscribe(ISocketActionListener iSocketActionListener) {
          // Socket behavior monitoring is not empty and the collection does not contain
          if (iSocketActionListener != null & amp; & amp; !actionListeners.contains(iSocketActionListener)) {
              actionListeners. add(iSocketActionListener);
          }
      }

      @Override
      public void unSubscribe(ISocketActionListener iSocketActionListener) {
          actionListeners. remove(iSocketActionListener);
      }

      /**
       * dispatch thread
       */
      private class DispatchThread extends Thread {
          public DispatchThread(@NonNull String name) {
              super(name);
          }

          @Override
          public void run() {
              // Loop processing Socket behavior distribution information
              while (!isStop) {
                  try {
                      ActionBean actionBean = actions. take();
                      if (actionBean != null & amp; & amp; actionBean. mDispatcher != null) {
                          //Get the Socket behavior dispatcher
                          SocketActionDispatcher actionDispatcher = actionBean.mDispatcher;
                          List<ISocketActionListener> copyListeners = new ArrayList<>(actionDispatcher. actionListeners);
                          // collection iterator
                          Iterator<ISocketActionListener> listeners = copyListeners. iterator();
                          // traverse the collection and notify all listeners
                          while (listeners. hasNext()) {
                              ISocketActionListener listener = listeners. next();
                              // Dispatch actions to listeners
                              //LogUtil.i(actionBean.mAction);
                              actionDispatcher.dispatchActionToListener(actionBean.mAction, actionBean.mArg, listener);
                          }
                      }
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                      LogUtil.e(e.getMessage());
                  }
              }
          }
      }

      /**
       * dispatch behavior to listeners
       *
       * @param action behavior
       * @param serializable parameter
       * @param socketActionListener Socket behavior monitoring
       */
      private void dispatchActionToListener(String action, final Serializable serializable, final ISocketActionListener socketActionListener) {
          switch (action) {
              // connection succeeded
              case ACTION_CONNECT_SUCCESS:
                  mainThreadExecutor.execute(() -> socketActionListener.onSocketConnectSuccess(socketAddress));
                  break;
              // Connection failed
              case ACTION_CONNECT_FAIL:
                  mainThreadExecutor.execute(() -> socketActionListener.onSocketConnectFail(socketAddress, (Boolean) serializable));
                  break;
              // Disconnect
              case ACTION_DISCONNECTION:
                  mainThreadExecutor.execute(() -> socketActionListener.onSocketDisconnect(socketAddress, (Boolean) serializable));
                  break;
          }
      }

      /**
       * Start dispatching threads
       */
      private void startDispatchThread() {
          if (!isStop) {
              isStop = false;
              actionThread = new DispatchThread("Dispatch thread");
              actionThread. start();
          }
      }

      @Override
      public void stopDispatchThread() throws InterruptedException {
          if (actionThread != null & amp; & amp; actionThread.isAlive() & amp; & amp; !actionThread.isInterrupted()) {
              isStop = true;
              // interrupt thread
              actionThread. interrupt();
              actionThread. join();
              actionThread = null;
              //LogUtil.i("stopDispatchThread");
          }
      }
  }

4. Test Behavior Dispatcher

 private void initView(View view) {
          SocketAddress socketAddress = new SocketAddress("192.168.1.52", 8866);
          SocketActionDispatcher actionDispatcher = new SocketActionDispatcher(socketAddress);
          view.findViewById(R.id.but_add_dispatch).setOnClickListener(v -> actionDispatcher.dispatchAction(SocketAction.ACTION_CONNECT_SUCCESS));
          view.findViewById(R.id.but_add_listener).setOnClickListener(v -> actionDispatcher.subscribe(listener));
          view.findViewById(R.id.but_remove_listener).setOnClickListener(v -> actionDispatcher.unSubscribe(listener));
      }

      //Socket behavior monitoring
      private ISocketActionListener listener = new ISocketActionListener() {
          @Override
          public void onSocketConnectSuccess(SocketAddress socketAddress) {
              LogUtil.i(socketAddress.getIp());
          }

          @Override
          public void onSocketConnectFail(SocketAddress socketAddress, boolean isNeedReconnect) {

          }

          @Override
          public void onSocketDisconnect(SocketAddress socketAddress, boolean isNeedReconnect) {

          }
      };

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge Java skill tree Network programmingTCP communication 108680 people are learning the system