nkzawa / socket.io-android-chat

A simple chat demo for socket.io and Android
MIT License
2k stars 692 forks source link

How to connect to a socket server on SSL/HTTPS? #19

Open raiehtisham opened 9 years ago

raiehtisham commented 9 years ago

I am unable to find any reference to making connection to https server. I have tested my server with a web based client and its working.

nkzawa commented 9 years ago

Please read README https://github.com/socketio/socket.io-client-java

ProductOfAmerica commented 6 years ago

@nkzawa myHostnameVerifier, myX509TrustManager, and mySSLContext aren't accounted for. Would you post a working example?

chathurangamdk commented 6 years ago

Hi All, Following code worked for me. You can try.

        IO.Options opts = new IO.Options();
        SSLContext mySSLContext = SSLContext.getInstance("TLS");
        TrustManager[] trustAllCerts= new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[] {};
            }

            public void checkClientTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }
        } };

        mySSLContext.init(null, trustAllCerts, null);

        HostnameVerifier myHostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        opts = new IO.Options();
        opts.sslContext = mySSLContext;
        opts.hostnameVerifier = myHostnameVerifier;
        mSocket = IO.socket(https://<yourURL>,opts);

Hope this will help. Have a nice day!

ProductOfAmerica commented 6 years ago

@chathurangamdk any idea how to implement this now? Both fields are now gone:

opts.sslContext = mySSLContext;
opts.hostnameVerifier = myHostnameVerifier;
ghost commented 6 years ago

@ProductOfAmerica here what you want

{
    try {
        String socketUrl = YOUR_HTTPS_URL;
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {

            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {

            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[0];
            }
        }};
        X509TrustManager trustManager = (X509TrustManager) trustAllCerts[0];

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .hostnameVerifier(hostnameVerifier)
                .sslSocketFactory(sslSocketFactory, trustManager)
                .build();

        IO.Options opts = new IO.Options();
        opts.callFactory = okHttpClient;
        opts.webSocketFactory = okHttpClient;
        mSocket = IO.socket(socketUrl, opts);
    } catch (URISyntaxException e) {
        throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
    }
}
ProductOfAmerica commented 6 years ago

@msalshaikh thank you so much, finally a working example

ghost commented 5 years ago

Thank you very much! Spent two days before finding your solution.

nicemak commented 5 years ago

Library info: implementation('io.socket:socket.io-client:0.8.3') { exclude group: 'org.json', module: 'json' }

opts.callFactory = okHttpClient; opts.webSocketFactory = okHttpClient;

unable to resolve callFactory and webSocketFactory, Please help.

ZainabAl-khabori commented 5 years ago

Still unable to connect to websocket using this code, or one that actually DOES verify hostname and validate certificate..

Whether through polling then upgrading to websocket, or directly using websocket only, my app still doesn't connect to websocket..

Please help..


    static {
        try {
            HostnameVerifier verifier = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
                    Log.v("SPLASH_HOSTNAME", "" + hostnameVerifier.verify("mgas006-mgas-ws.webware.om", session));
                    return hostnameVerifier.verify("mgas006-mgas-ws.webware.om", session);
                }
            };

            TrustManager[] trustAll = new TrustManager[] {
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            try {
                                chain[0].checkValidity();
                            } catch (Exception e) {
                                throw new CertificateException("Certificate not valid or trusted.");
                            }
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            try {
                                chain[0].checkValidity();
                                Log.v("SPLASH_SOCKET", "trusted");
                            } catch (Exception e) {
                                Log.v("SPLASH_SOCKET", "untrusted");
                                throw new CertificateException("Certificate not valid or trusted.");
                            }
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }
                    }
            };

            X509TrustManager trustManager = (X509TrustManager)trustAll[0];

            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, trustAll, null);

            OkHttpClient client = new OkHttpClient.Builder()
                    .hostnameVerifier(verifier)
                    .sslSocketFactory(context.getSocketFactory(), trustManager)
                    .build();

            IO.Options options = new IO.Options();
            options.callFactory = client;
            options.webSocketFactory = client;
            options.transports = new String[] {WebSocket.NAME};

            Log.v("SPLASH_NAME", WebSocket.NAME);

            socket = IO.socket(MGasApi.HOST, options);
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }
derrylieyanto commented 4 years ago

finally working. use this library in app build.gradle : implementation('io.socket:socket.io-client:1.0.0') { exclude group: 'org.json', module: 'json' } instead implementation 'com.github.nkzawa:socket.io-client:0.6.0'

then use code from

@ghost

@ProductOfAmerica here what you want

{
    try {
        String socketUrl = YOUR_HTTPS_URL;
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {

            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {

            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[0];
            }
        }};
        X509TrustManager trustManager = (X509TrustManager) trustAllCerts[0];

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, null);
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .hostnameVerifier(hostnameVerifier)
                .sslSocketFactory(sslSocketFactory, trustManager)
                .build();

        IO.Options opts = new IO.Options();
        opts.callFactory = okHttpClient;
        opts.webSocketFactory = okHttpClient;
        mSocket = IO.socket(socketUrl, opts);
    } catch (URISyntaxException e) {
        throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
    }
}