From 223039ffc182d9fc9ee9bf4d7c3e7d6f24df0295 Mon Sep 17 00:00:00 2001 From: lxien Date: Sun, 30 Aug 2026 18:20:25 +0800 Subject: [PATCH] refactor(client-java): use host:port format for server config --- .../lxien/orbien/client/OrbienClient.java | 13 ++- .../orbien/client/OrbienClientConfig.java | 92 ++++++++++++++++--- .../orbien/client/netty/ControlHandler.java | 4 +- .../src/main/resources/application-easy.yml | 2 +- .../src/main/resources/application-full.yml | 3 +- .../lxien/orbien/boot/OrbienProperties.java | 24 ++--- docs/docs/integrations/springboot.mdx | 5 +- .../current/integrations/springboot.mdx | 5 +- 8 files changed, 107 insertions(+), 41 deletions(-) diff --git a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClient.java b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClient.java index 1893dca..6fc3767 100644 --- a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClient.java +++ b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClient.java @@ -89,14 +89,14 @@ public final class OrbienClient implements AutoCloseable { }); ChannelFuture cf = - b.connect(config.getServerAddr(), config.getServerPort()).sync(); + b.connect(connectHost(config.getServerHost()), config.getServerPort()).sync(); controlChannel = cf.channel(); sendLogin(controlChannel, previousSessionId); String id = loginFuture.get(30, TimeUnit.SECONDS); config.setSessionId(id); SessionIdStore.save(sessionIdPath, id); - log.info("connected to {}:{} sessionId={}", config.getServerAddr(), config.getServerPort(), id); + log.info("connected to {} sessionId={}", config.getServer(), id); } catch (Exception e) { close(); throw new IllegalStateException("failed to start Orbien client: " + e.getMessage(), e); @@ -161,7 +161,7 @@ public final class OrbienClient implements AutoCloseable { } }); - b.connect(config.getServerAddr(), config.getServerPort()) + b.connect(connectHost(config.getServerHost()), config.getServerPort()) .addListener(f -> { if (!f.isSuccess()) { log.error("failed to open data connection", f.cause()); @@ -178,6 +178,13 @@ public final class OrbienClient implements AutoCloseable { }); } + private static String connectHost(String host) { + if (host != null && host.startsWith("[") && host.endsWith("]") && host.length() > 2) { + return host.substring(1, host.length() - 1); + } + return host; + } + private static String localHostname() { try { String h = InetAddress.getLocalHost().getHostName(); diff --git a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClientConfig.java b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClientConfig.java index a82d35f..c9f5cef 100644 --- a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClientConfig.java +++ b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/OrbienClientConfig.java @@ -5,8 +5,11 @@ import java.util.List; import java.util.Objects; public final class OrbienClientConfig { - private String serverAddr = "127.0.0.1"; - private int serverPort = 9527; + private static final String DEFAULT_SERVER = "127.0.0.1:9527"; + private static final int DEFAULT_PORT = 9527; + + private String server = DEFAULT_SERVER; + private String token = ""; private boolean tcpMux = false; private int poolCount = 1; @@ -16,20 +19,23 @@ public final class OrbienClientConfig { private int heartbeatIntervalSecs = 30; private final List tunnels = new ArrayList<>(); - public String getServerAddr() { - return serverAddr; + public String getServer() { + return server; } - public void setServerAddr(String serverAddr) { - this.serverAddr = Objects.requireNonNull(serverAddr, "serverAddr"); + public void setServer(String server) { + this.server = Objects.requireNonNull(server, "server").trim(); + if (this.server.isEmpty()) { + this.server = DEFAULT_SERVER; + } + } + + public String getServerHost() { + return parseHostPort(server).host; } public int getServerPort() { - return serverPort; - } - - public void setServerPort(int serverPort) { - this.serverPort = serverPort; + return parseHostPort(server).port; } public String getToken() { @@ -92,6 +98,70 @@ public final class OrbienClientConfig { return tunnels; } + static HostPort parseHostPort(String raw) { + String s = raw == null ? "" : raw.trim(); + if (s.isEmpty()) { + return new HostPort("127.0.0.1", DEFAULT_PORT); + } + + if (s.startsWith("[")) { + int close = s.indexOf(']'); + if (close < 0) { + throw new IllegalArgumentException("invalid server address '" + raw + "': missing ']'"); + } + String hostInner = s.substring(1, close); + if (hostInner.isEmpty()) { + throw new IllegalArgumentException("invalid server address '" + raw + "': empty IPv6 host"); + } + String host = "[" + hostInner + "]"; + String after = s.substring(close + 1); + if (after.isEmpty()) { + return new HostPort(host, DEFAULT_PORT); + } + if (!after.startsWith(":")) { + throw new IllegalArgumentException( + "invalid server address '" + raw + "': expected ':' after ']'"); + } + String portStr = after.substring(1); + if (portStr.isEmpty()) { + return new HostPort(host, DEFAULT_PORT); + } + int port = parsePort(portStr, raw); + return new HostPort(host, port == 0 ? DEFAULT_PORT : port); + } + + int colon = s.lastIndexOf(':'); + if (colon > 0 && s.indexOf(':') == colon) { + String host = s.substring(0, colon); + String portStr = s.substring(colon + 1); + if (portStr.isEmpty()) { + return new HostPort(host, DEFAULT_PORT); + } + int port = parsePort(portStr, raw); + return new HostPort(host, port == 0 ? DEFAULT_PORT : port); + } + + return new HostPort(s, DEFAULT_PORT); + } + + private static int parsePort(String portStr, String raw) { + try { + return Integer.parseInt(portStr); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("invalid server port in '" + raw + "'", e); + } + } + + static final class HostPort { + final String host; + final int port; + + HostPort(String host, int port) { + this.host = host; + this.port = port; + } + } + public static final class TunnelConfig { private String protocol = "tcp"; private String name; diff --git a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/netty/ControlHandler.java b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/netty/ControlHandler.java index 470be2b..e36bb9c 100644 --- a/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/netty/ControlHandler.java +++ b/client-java/orbien-client/src/main/java/io/github/lxien/orbien/client/netty/ControlHandler.java @@ -144,10 +144,10 @@ public final class ControlHandler extends SimpleChannelInboundHandler 0) { - remote = config.getServerAddr() + ":" + tunnel.getRemotePort(); + remote = config.getServerHost() + ":" + tunnel.getRemotePort(); } else { return "?"; } diff --git a/client-java/orbien-spring-boot-demo/src/main/resources/application-easy.yml b/client-java/orbien-spring-boot-demo/src/main/resources/application-easy.yml index c0f240e..84c9db7 100644 --- a/client-java/orbien-spring-boot-demo/src/main/resources/application-easy.yml +++ b/client-java/orbien-spring-boot-demo/src/main/resources/application-easy.yml @@ -1,6 +1,6 @@ orbien: enabled: true - server-addr: 127.0.0.1 + server: "127.0.0.1:9527" token: YOUR_TOKEN tunnel: protocol: http diff --git a/client-java/orbien-spring-boot-demo/src/main/resources/application-full.yml b/client-java/orbien-spring-boot-demo/src/main/resources/application-full.yml index 4b34138..7922059 100644 --- a/client-java/orbien-spring-boot-demo/src/main/resources/application-full.yml +++ b/client-java/orbien-spring-boot-demo/src/main/resources/application-full.yml @@ -1,7 +1,6 @@ orbien: enabled: true - server-addr: 127.0.0.1 - server-port: 9527 + server: "127.0.0.1:9527" token: YOUR_TOKEN tcp-mux: false pool-count: 1 diff --git a/client-java/orbien-spring-boot-starter/src/main/java/io/github/lxien/orbien/boot/OrbienProperties.java b/client-java/orbien-spring-boot-starter/src/main/java/io/github/lxien/orbien/boot/OrbienProperties.java index 2be9bfa..d5c15a1 100644 --- a/client-java/orbien-spring-boot-starter/src/main/java/io/github/lxien/orbien/boot/OrbienProperties.java +++ b/client-java/orbien-spring-boot-starter/src/main/java/io/github/lxien/orbien/boot/OrbienProperties.java @@ -12,9 +12,10 @@ import org.springframework.util.StringUtils; @ConfigurationProperties(prefix = "orbien") public class OrbienProperties { private static final String DEFAULT_LOCAL_IP = "127.0.0.1"; + private static final String DEFAULT_SERVER = "127.0.0.1:9527"; + private boolean enabled = true; - private String serverAddr = "127.0.0.1"; - private int serverPort = 9527; + private String server = DEFAULT_SERVER; private String token = ""; private boolean tcpMux = false; private int poolCount = 1; @@ -34,20 +35,12 @@ public class OrbienProperties { this.enabled = enabled; } - public String getServerAddr() { - return serverAddr; + public String getServer() { + return server; } - public void setServerAddr(String serverAddr) { - this.serverAddr = serverAddr; - } - - public int getServerPort() { - return serverPort; - } - - public void setServerPort(int serverPort) { - this.serverPort = serverPort; + public void setServer(String server) { + this.server = StringUtils.hasText(server) ? server.trim() : DEFAULT_SERVER; } public String getToken() { @@ -119,8 +112,7 @@ public class OrbienProperties { public OrbienClientConfig toClientConfig() { OrbienClientConfig cfg = new OrbienClientConfig(); - cfg.setServerAddr(serverAddr); - cfg.setServerPort(serverPort); + cfg.setServer(server); cfg.setToken(token); cfg.setTcpMux(tcpMux); cfg.setPoolCount(poolCount); diff --git a/docs/docs/integrations/springboot.mdx b/docs/docs/integrations/springboot.mdx index b27efd7..fb6fca8 100644 --- a/docs/docs/integrations/springboot.mdx +++ b/docs/docs/integrations/springboot.mdx @@ -38,7 +38,7 @@ import TabItem from '@theme/TabItem'; # application.yml orbien: enabled: true - server-addr: 127.0.0.1 + server: "127.0.0.1:9527" # token: YOUR_TOKEN # 可选 tunnel: protocol: http @@ -63,8 +63,7 @@ tcpMux = false # 关闭 TCP 多路复用 # application.yml orbien: enabled: true - server-addr: 127.0.0.1 - server-port: 9527 + server: "127.0.0.1:9527" token: YOUR_TOKEN tcp-mux: false # 必须为 false,且与服务端一致 pool-count: 1 # 登录时预申请的数据连接池大小 diff --git a/docs/i18n/en/docusaurus-plugin-content-docs/current/integrations/springboot.mdx b/docs/i18n/en/docusaurus-plugin-content-docs/current/integrations/springboot.mdx index afa226a..815510c 100644 --- a/docs/i18n/en/docusaurus-plugin-content-docs/current/integrations/springboot.mdx +++ b/docs/i18n/en/docusaurus-plugin-content-docs/current/integrations/springboot.mdx @@ -38,7 +38,7 @@ import TabItem from '@theme/TabItem'; # application.yml orbien: enabled: true - server-addr: 127.0.0.1 + server: "127.0.0.1:9527" # token: YOUR_TOKEN # optional tunnel: protocol: http @@ -63,8 +63,7 @@ tcpMux = false # disable TCP multiplexing # application.yml orbien: enabled: true - server-addr: 127.0.0.1 - server-port: 9527 + server: "127.0.0.1:9527" token: YOUR_TOKEN tcp-mux: false # must be false and match the server pool-count: 1 # data-connection pool size requested at login