使用org.java-websocket包的Java-WebSocket实现wss调用时报错如下:
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 192.168.65.173 found。
服务端提示:SSL Handshake error:ssLV3 alert certificate unknown (SSL routines)
所以转换思路,使用jetty实现
依赖包:
<dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-client</artifactId> <version>9.4.53.v20231009</version> </dependency> <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>websocket-client</artifactId> <version>9.4.53.v20231009</version> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> <version>9.4.53.v20231009</version> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> <version>9.4.53.v20231009</version> </dependency>
代码亲测可用:
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import java.net.URI;
import java.util.concurrent.TimeUnit;
public class JettyWssClient {
public static void main(String[] args) throws Exception {
String destUri = "wss://192.168.65.173:10304";
// 1. 创建 SslContextFactory,忽略所有证书和主机名验证
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setTrustAll(true); // 忽略证书验证
sslContextFactory.setEndpointIdentificationAlgorithm(null); // 忽略主机名验证(关键)
// 2. 创建 HttpClient
HttpClient httpClient = new HttpClient(sslContextFactory);
httpClient.start();
// 3. 创建 WebSocket 客户端
WebSocketClient client = new WebSocketClient(httpClient);
client.start();
// 4. 创建自定义 socket 行为
SimpleSocket socket = new SimpleSocket();
URI echoUri = new URI(destUri);
ClientUpgradeRequest request = new ClientUpgradeRequest();
System.out.println("Connecting to: " + echoUri);
client.connect(socket, echoUri, request);
// 等待连接和通信
socket.awaitClose(10, TimeUnit.SECONDS);
//client.stop();
//httpClient.stop();
}
}
package com.hnac.hz3000.pdec.issue.service.impl;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@WebSocket
public class SimpleSocket {
private final CountDownLatch closeLatch = new CountDownLatch(1);
private Session session;
public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException {
return closeLatch.await(duration, unit);
}
@OnWebSocketConnect
public void onConnect(Session session) {
System.out.println(">> Connected");
this.session = session;
try {
String message = "hello";
System.out.println(">> Sending: " + message);
session.getRemote().sendString(message);
} catch (Throwable t) {
t.printStackTrace();
}
}
@OnWebSocketMessage
public void onMessage(String msg) {
System.out.println("<< Received: " + msg);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
System.out.println(">> Closed: " + statusCode + " - " + reason);
closeLatch.countDown();
}
@OnWebSocketError
public void onError(Throwable cause) {
System.err.println(">> Error: " + cause.getMessage());
cause.printStackTrace();
}
}