如何设置 Android Socket.io 客户端?

How to setup an Android Socket.io client?

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

它在下面的 android link 中有一个示例聊天应用程序:
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();
    }

}
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);
}

public 抽象 class 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);
}

}