【问题标题】:How to setup an Android Socket.io client?如何设置 Android Socket.io 客户端?
【发布时间】:2018-05-31 05:08:24
【问题描述】:

在我为多房间聊天应用程序创建 SOCKET.IO 服务器之后 如何使用 https://github.com/socketio/socket.io-client-java 创建 android 客户端? 我已经搜索了很多,但没有在 socket.io for android 的客户端找到最新的示例,大多数教程和示例都是针对 node.js 的服务器端的。

【问题讨论】:

    标签: android node.js websocket socket.io socket.io-java-client


    【解决方案1】:

    它有一个在下面的 android 链接中实现的示例聊天应用程序:
    https://github.com/nkzawa/socket.io-android-chat

    无论如何,对于在 android 中使用 socket.io,我认为最好的方法是在这样的服务中使用它:

        public class ChatService extends Service {
    
    
    
        public void connectSocket() {
            try {
                IO.Options options = new IO.Options();
    
                socket = IO.socket("http://192.168.1.1:8080", options);
                socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
    
                    }
    
                }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
    
                    }
                }).on("error", new Emitter.Listener() {
                    @Override
                    public void call(Object... args) {
    
                    }
                });
    
                socket.connect();
    
            } catch (Exception ignored) {
            }
        }
    
        @Override
        public void onDestroy() {
            socket.disconnect();
            super.onDestroy();
        }
    
    }
    

    【讨论】:

      【解决方案2】:
      private static NetworkManager mInstance;
      private static NetworkInterface mNetworkInterface;
      private Socket mSocket;
      private int RECONNECTION_ATTEMPT = 10;
      private long CONNECTION_TIMEOUT = 30000;
      
      /**
       * The purpose of this method is to get the call back for any type of connection error
       */
      private Emitter.Listener testing = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              Log.e("Response", args[0].toString());
          }
      };
      
      /**
       * The purpose of this method is to get the call back for any type of connection error
       */
      private Emitter.Listener onConnectionError = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              Log.e("Response", "onConnectionError");
              mNetworkInterface.networkCallReceive(NetworkSocketConstant.SERVER_CONNECTION_ERROR, args);
          }
      };
      /**
       * The purpose of this method to get the call back for connection getting timed out
       */
      private Emitter.Listener onConnectionTimeOut = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              Log.e("Response", "onConnectionTimeOut");
              mNetworkInterface.networkCallReceive(NetworkSocketConstant.SERVER_CONNECTION_TIMEOUT, args);
          }
      };
      /**
       * The purpose of this method is to receive the call back when the server get connected
       */
      private Emitter.Listener onServerConnect = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              Log.e("Response", "onServerConnected");
              mNetworkInterface.networkCallReceive(NetworkSocketConstant.SERVER_CONNECTED, args);
          }
      };
      
      /**
       * The purpose of this method is to receive the call back when the server get disconnected
       */
      private Emitter.Listener onServerDisconnect = new Emitter.Listener() {
          @Override
          public void call(Object... args) {
              Log.e("Response", "onServerDisconnection");
              mNetworkInterface.networkCallReceive(NetworkSocketConstant.SERVER_DISCONNECTED, args);
          }
      };
      
      
      
      public static NetworkManager getInstance(Context context) {
          if (mInstance == null) {
              mInstance = new NetworkManager();
          }
          return mInstance;
      }
      
      public void registerInterface(NetworkInterface interfaces) {
          mNetworkInterface = interfaces;
      }
      
      /**
       * The purpose of this method to create the socket object
       */
      public void connectToSocket() {
          try {
              IO.Options opts = new IO.Options();
              opts.timeout = CONNECTION_TIMEOUT;
              opts.reconnection = true;
              opts.reconnectionAttempts = RECONNECTION_ATTEMPT;
              opts.reconnectionDelay = 1000;
              opts.forceNew = true;
              mSocket = IO.socket(NetworkSocketConstant.SOCKET_CONNECTION_URL, opts);
              makeConnection();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      
      /**
       * The purpose of the method is to return the instance of socket
       *
       * @return
       */
      public Socket getSocket() {
          return mSocket;
      }
      
      /**
       * The purpose of this method is to connect with the socket
       */
      
      public void makeConnection() {
          if (mSocket != null) {
              registerConnectionAttributes();
              mSocket.connect();
          }
      
      }
      
      /**
       * The purpose of this method is to disconnect from the socket interface
       */
      public void disconnectFromSocket() {
          unregisterConnectionAttributes();
          if (mSocket != null) {
              mSocket.disconnect();
              mSocket = null;
              mInstance = null;
              BaseApplicationActivty.networkManager = null;
          }
      }
      
      /**
       * The purpose of this method is to register default connection attributes
       */
      public void registerConnectionAttributes() {
          try {
              if (mSocket != null) {
                  mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectionError);
                  mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectionTimeOut);
                  mSocket.on(Socket.EVENT_DISCONNECT, onServerDisconnect);
                  mSocket.on(Socket.EVENT_CONNECT, onServerConnect);
                  registerHandlers();
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      
      }
      
      /**
       * The purpose of this method is to unregister default connection attributes
       */
      public void unregisterConnectionAttributes() {
          try {
              if (mSocket != null) {
                  mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectionError);
                  mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectionTimeOut);
                  mSocket.off(Socket.EVENT_DISCONNECT, onServerDisconnect);
                  mSocket.off(Socket.EVENT_CONNECT, onServerConnect);
                  unRegisterHandlers();
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      
      /**
       * The purpose of this method is to unregister the connection from the socket
       */
      private void unRegisterHandlers() {
          try {
              //unregister your all methods here
              mSocket.off("hello", testing);
              mSocket.off("android", testing);
              mSocket.off("hello2", testing);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      /**
       * The purpose of this method is to register the connection from the socket
       */
      private void registerHandlers() {
          try {
              //register you all method here
              mSocket.on("hello", testing);
              mSocket.on("android", testing);
              mSocket.on("hello2", testing);
          } catch (Exception e) {
              e.printStackTrace();
          }
      
      }
      
      
      /**
       * The purpose of this method is register a single method on server
       *
       * @param methodOnServer
       * @param handlerName
       */
      public void registerHandler(String methodOnServer, Emitter.Listener handlerName) {
          try {
              if (mSocket != null) {
                  mSocket.on(methodOnServer, handlerName);
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      /**
       * The purpose of this method is to unregister a single method from server
       *
       * @param methodOnServer
       * @param handlerName
       */
      public void unRegisterHandler(String methodOnServer, Emitter.Listener handlerName) {
          try {
              if (mSocket != null) {
                  mSocket.off(methodOnServer, handlerName);
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      /**
       * The purpose of this method is to send the data to the server
       *
       * @param methodOnServer
       * @param request
       */
      public void sendDataToServer(String methodOnServer, JsonObject request) {
      
          try {
              if (mSocket != null && mSocket.connected()) {
                  Log.e("JSON ", request.toString());
                  mSocket.emit(methodOnServer, request);
              } else {
                  mNetworkInterface.networkCallReceive(NetworkSocketConstant.SERVER_CONNECTION_ERROR);
              }
          } catch (Exception e) {
              e.printStackTrace();
          }
      
      }
      
      public interface NetworkInterface {
          void networkCallReceive(int responseType, Object... args);
      }
      

      公共抽象类 BaseActivity 扩展 AppCompatActivity {

      /**
       * The purpose of this method is to receive the callback from the server
       */
      private NetworkManager.NetworkInterface networkInterface = new NetworkManager.NetworkInterface() {
          @Override
          public void networkCallReceive(int responseType, Object... args) {
              switch (responseType) {
                  case NetworkSocketConstant.SERVER_CONNECTION_TIMEOUT:
                      runOnUiThread(new Runnable() {
                          public void run() {
                              Toast.makeText(BaseActivity.this, getResources().getString(R.string.sorry_no_internet_connection), Toast.LENGTH_SHORT).show();
                          }
                      });
                      break;
                  case NetworkSocketConstant.SERVER_CONNECTION_ERROR:
                      runOnUiThread(new Runnable() {
                          public void run() {
                              Toast.makeText(BaseActivity.this, (getResources().getString(R.string.connection_error)), Toast.LENGTH_SHORT).show();
                          }
                      });
                      break;
                  case NetworkSocketConstant.SERVER_CONNECTED:
                      SharedPreferenceUtility sharedPreferenceUtility = new SharedPreferenceUtility(BaseActivity.this);
                      if (sharedPreferenceUtility.getUserId() != null && !sharedPreferenceUtility.getUserId().isEmpty()) {
                           SocketEmitter.emitSocketConnectionService(BaseActivity.this);
                          SocketEmitter.emitTesting(BaseActivity.this, "android");
                      }
                      break;
                  case NetworkSocketConstant.SERVER_DISCONNECTED:
                      runOnUiThread(new Runnable() {
                          public void run() {
                              Toast.makeText(BaseActivity.this, getResources().getString(R.string.disconnected), Toast.LENGTH_SHORT).show();
                          }
                      });
                      break;
          }
      };
      
      
      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          socketInit();
      
      }
      
      // initialization socket
      private void socketInit() {
          if (BaseApplicationActivty.networkManager == null) {
              BaseApplicationActivty.networkManager = NetworkManager.getInstance(getApplicationContext());
              BaseApplicationActivty.networkManager.registerInterface(networkInterface);
              BaseApplicationActivty.networkManager.connectToSocket();
          } else {
              BaseApplicationActivty.networkManager.registerInterface(networkInterface);
          }
      }
      
      /**
       * This Method must call all ui fragment/activity using Rx subs.
       */
      protected abstract void onPermissionResult(int requestCode, boolean isPermissionGranted);
      
      /**
       * This Method must call all ui fragment/activity using Rx subs.
       */
      protected abstract void onSocketApiResult(int requestCode, Object... args);
      
      /**
       * Request For Permission of particular type.
       *
       * @param requestCode
       * @param permission
       * @return
       */
      public boolean requestPermission(int requestCode, String... permission) {
      
          boolean isAlreadyGranted = false;
      
          isAlreadyGranted = checkPermission(permission);
      
          if (!isAlreadyGranted)
              ActivityCompat.requestPermissions(this, permission, requestCode);
      
          return isAlreadyGranted;
      
      }
      
      protected boolean checkPermission(String[] permission) {
      
          boolean isPermission = true;
          for (String s : permission)
              isPermission = isPermission && ContextCompat.checkSelfPermission(this, s) == PackageManager.PERMISSION_GRANTED;
      
          return isPermission;
      }
      
      @Override
      public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
      
          if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
      
              onPermissionResult(requestCode, true);
      
          } else {
      
              onPermissionResult(requestCode, false);
              Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_LONG).show();
      
          }
      
      }
      
      
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
      }
      

      }

      【讨论】:

      • 请在第一块代码中。你把所有这些放在哪里。在服务中?而且我找不到 NetworkManager。谢谢
      • 欢迎提供一些解释。例如,定义的函数disconnectFromSocket() 永远不会被调用。什么时候应该调用它?还是没用?还有,socket的forceNew选项有什么用?
      • 我可以将 mSocket 设为静态变量吗?
      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多