java将https升级为wss(k8s sdk)
使用kubernetes的client-java(原理和步骤类似,因为我们项目使用java做k8s的二开,所以我的例子也是用的k8s client-java sdk)使用 gorilla,相对来说比较简单,go提供了特别强大的功能,因此就不写了(有需要留言,我给你写),下面着重写一下使用java如何实现。因此:需要用代码实现 nginx 对应配置的功能。优点:不需要做配置,可以直接将请求代理到ws
·
背景:https和wss这两个协议的关系自行百度,结论:https 加上特定的请求头,就会升级为wss请求
有人会杠:这个功能nginx已经实现:比如如下配置:
proxy_ssl_certificate /opt/required/nginx/ssl/k8s-server.crt;
proxy_ssl_certificate_key /opt/required/nginx/ssl/k8s-server.key;
location /wss/ {
proxy_pass https://k8s.test.com:6443/apis/subresources.kubevirt.io/v1/namespaces/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
优点:不需要做配置,可以直接将请求代理到wss
缺点:不能对接口进行鉴权,换环境就需要换证书
因此:需要用代码实现 nginx 对应配置的功能
go语言实现
使用 gorilla,相对来说比较简单,go提供了特别强大的功能,因此就不写了(有需要留言,我给你写),下面着重写一下使用java如何实现
java实现
前置条件:
使用okhttp
使用kubernetes的client-java(原理和步骤类似,因为我们项目使用java做k8s的二开,所以我的例子也是用的k8s client-java sdk)
代码:
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Pair;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
public class Test {
public static final String WEBSOCKET = "websocket";
public static final String CONNECTION = "Connection";
public static final String UPGRADE = "Upgrade";
public static void main(String[] args) throws IOException, ApiException {
String config = "你自己的k8s config文件的内容";
HashMap<String, String> headers = new HashMap<String, String>();
// https请求升级为wss
headers.put(CONNECTION, UPGRADE);
headers.put(UPGRADE, WEBSOCKET);
String[] localVarAuthNames = new String[] {"BearerToken"};
// 如下是使用k8s 创建的request,如果需要其他方式创建requst也是可以的,可以自行百度一下,
// 如何使用java 发送 https请求
ApiClient client = ClientBuilder.kubeconfig(
KubeConfig.loadKubeConfig(new BufferedReader(new StringReader(config))))
.build();
Request request =
client.buildRequest(
"/apis/subresources.kubevirt.io/v1/namespaces/vm/virtualmachineinstances/centos/vnc",
"GET",
new ArrayList<Pair>(),
new ArrayList<Pair>(),
null,
headers,
new HashMap<String, String>(),
new HashMap<String, Object>(),
localVarAuthNames,
null);
WebSocket webSocket =
client
.getHttpClient()
.newWebSocket(
request,
new WebSocketListener() {
@Override
public void onClosed(
@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosed(webSocket, code, reason);
}
@Override
public void onClosing(
@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosing(webSocket, code, reason);
}
@Override
public void onFailure(
@NotNull WebSocket webSocket,
@NotNull Throwable t,
@Nullable Response response) {
super.onFailure(webSocket, t, response);
}
// 收到文本数据
@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
System.out.println("onMessage with text:" + text);
}
// 收到二进制数据
// 至于文本数据和二进制数据哪个收到,要看客户端是如何发的,如果不知道是哪个发的,那么请在
// 两个onMessage方法中打印日志,那么就可以看到哪个可以接收到相应数据
@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull ByteString bytes) {
System.out.println("onMessage with ByteString:" + new String(bytes.toByteArray()));
}
@Override
public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
super.onOpen(webSocket, response);
}
});
// 发送文本数据数据
webSocket.send("hello");
// 发送二进制数据,同理:二选其一,具体使用哪个发数据,需要知道服务端是如何定义的,
// 如果不知道 哪个可以发成功,请两个都尝试一下
webSocket.send(ByteString.of("hello".getBytes(StandardCharsets.UTF_8)));
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)