#java #spring-boot #socket.io
Вопрос:
Мы использовали сокет.сервер ввода-вывода v2.3.0 без SSL. Клиент js frontend и клиент spring boot отправляли и получали сообщения с помощью этого сокета.сервер ввода-вывода.
Теперь мы используем SSL. Интерфейс js работает правильно, но клиент spring boot не отправляет никаких сообщений в сокет.сервер ввода-вывода. Вот мой исходный код для отправки сообщений в сокет.сервер ввода-вывода. Он работал без ssl. Я изменил URL-адрес и установил для этого HTTPS.
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);
В чем проблема? версии выглядят следующим образом:
Сервер сокетов:2.3.0
Клиент js сокета: 2.3.0
Клиент ввода-вывода сокета: 1.0.0
Ответ №1:
Проблема решается добавлением статического класса и передачей параметров сокета этой функции. Он добавляет некоторые параметры к опции и решает проблему.
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;
}
}
Исходный код изменился на следующий:
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);