socketio / socket.io-client-java

Full-featured Socket.IO Client Library for Java, which is compatible with Socket.IO v1.0 and later.
https://socketio.github.io/socket.io-client-java/installation.html
Other
5.32k stars 972 forks source link

Spring Boot socket-io-client v1 does not emit to the socket.io server with ssl #676

Closed shahabes closed 3 years ago

shahabes commented 3 years ago

Hello, my friends. We were using socket.io server v2.3.0 without SSL. The js frontend client and the spring boot client were sending and receiving messages using that socket.io server. Now, we are using SSL. The js frontend is working properly but the spring boot client does not emit any messages to the socket.io server. Here is my source code for emitting messages to the socket.io server. It was working without ssl. I changed the URL and set HTTPS for that.

    IO.Options options = new IO.Options();
    options.transports = new String[]{"websocket"};
    options.reconnectionAttempts = 2;
    options.reconnectionDelay = 1000;
    options.timeout = 500;

    final Socket socket = IO.socket(socketServerURL, options);
    socket.on(Socket.EVENT_CONNECT, args1 -> socket.send("hello..."));
    socket.on("connected", objects -> System.out.println("Server connected: " + objects[0].toString()));
    socket.on("push_data_event", objects -> System.out.println("Server:" + objects[0].toString()));
    socket.on("myBroadcast", objects -> System.out.println("Server:" + objects[0].toString()));
    socket.connect();
    socket.emit("chanel_name", message);

What is the problem? the versions are like the following: Socket server:2.3.0 Socket js client: 2.3.0 Socket io-client: 1.0.0

shahabes commented 3 years ago

The problem is solved by adding a static class and pass the options of the socket to this function. It adds some parameters to the option and solves the problem.

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import io.socket.client.IO;
import okhttp3.OkHttpClient;

public class SocketSSL {

    public static OkHttpClient getOkHttpClient() {

        try {

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            }}, new java.security.SecureRandom());

            OkHttpClient.Builder builder = new OkHttpClient.Builder();

            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            builder.sslSocketFactory(sc.getSocketFactory(), new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                }

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

            return builder.build();

        } catch (NoSuchAlgorithmException | KeyManagementException ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public static void set(IO.Options options) {
        OkHttpClient okHttpClient = getOkHttpClient();
        IO.setDefaultOkHttpWebSocketFactory(okHttpClient);
        IO.setDefaultOkHttpCallFactory(okHttpClient);
        options.callFactory = okHttpClient;
        options.webSocketFactory = okHttpClient;
    }
}

The source code changed to the following:

 IO.Options options = new IO.Options();
 options.transports = new String[]{"websocket"};
 options.reconnectionAttempts = 2;
 options.reconnectionDelay = 1000;
 options.timeout = 500;
 options.rememberUpgrade = true;
 options.secure = true;

 //usage of the class
 SocketSSL.set(options);

 final Socket socket = IO.socket(socketServerURL, options);
 socket.on(Socket.EVENT_CONNECT, args1 -> socket.send("hello..."));
 socket.on("connected", objects -> System.out.println("Server connected: " + objects[0].toString()));
 socket.on("push_data_event", objects -> System.out.println("Server:" + objects[0].toString()));
 socket.on("myBroadcast", objects -> System.out.println("Server:" + objects[0].toString()));

 socket.connect();
 socket.emit("chanel_name", message);