Documentation
¶
Index ¶
- Constants
- Variables
- func IsAPIError(err error) (code string, ok bool)
- type APIError
- type Client
- func (c *Client) Connect(ctx context.Context, cfg ConnectConfig) error
- func (c *Client) CreatePort(ctx context.Context, tunnelID string, port int, protocol string, ...) error
- func (c *Client) CreateTunnel(ctx context.Context, name, description string, expiration *int) (*Tunnel, error)
- func (c *Client) DeleteAllTunnels(ctx context.Context) error
- func (c *Client) DeletePort(ctx context.Context, tunnelID string, port int) error
- func (c *Client) DeleteTunnel(ctx context.Context, tunnelID string) error
- func (c *Client) GetLimits(ctx context.Context) (*Limits, error)
- func (c *Client) Host(ctx context.Context, cfg HostConfig) error
- func (c *Client) IssueToken(ctx context.Context, tunnelID, scope string) (*TunnelToken, error)
- func (c *Client) ListPorts(ctx context.Context, tunnelID string) ([]Port, error)
- func (c *Client) ListTunnels(ctx context.Context) ([]Tunnel, error)
- func (c *Client) ShowPort(ctx context.Context, tunnelID string, port int) (*Port, error)
- func (c *Client) ShowTunnel(ctx context.Context, tunnelID string) (*TunnelDetail, error)
- func (c *Client) UpdatePort(ctx context.Context, tunnelID string, port int, allowAnonymous *bool) error
- func (c *Client) UpdateTunnel(ctx context.Context, tunnelID string, name, description *string, ...) error
- type Config
- type ConnectConfig
- type Forwarding
- type HostConfig
- type HostResult
- type Limits
- type Port
- type Tunnel
- type TunnelDetail
- type TunnelStatus
- type TunnelToken
Examples ¶
Constants ¶
const ( // DefaultAPIBaseURL REST API 基础地址(与 CLI 生产环境对齐) // 对应 cli/.goreleaser.yaml 中注入的 DefaultServerDomain + cli/internal/api/client.go 的路径后缀 DefaultAPIBaseURL = "https://bridge.developer.myhuaweicloud.com/open-api-inner/v1/relay-controller" // DefaultGatewayAddr WebSocket 网关地址 DefaultGatewayAddr = "gateway.cn-north-4-bridge.myhuaweicloud.com:443" // DefaultGatewayHost WebSocket 网关 SNI host DefaultGatewayHost = "cn-north-4-bridge.myhuaweicloud.com" // DefaultClusterID 默认集群 DefaultClusterID = "cn-north-4-bridge" )
默认服务地址
const AllPortsSentinel = -1
AllPortsSentinel 表示"所有端口"的哨兵值,对应后端存储的 -1。 它只对 visitor URL 访问有意义(网关按 SNI 动态路由任意端口), host/connect 的 SSH 主动端口转发不应转发该值。
Variables ¶
var ErrDuplicateHost = errors.New("host already connected for this tunnel")
ErrDuplicateHost 该隧道已有 Host 在运行
var ErrInvalidPort = errors.New("invalid port number: must be 1-65535")
ErrInvalidPort 端口号无效
var ErrInvalidProtocol = errors.New("invalid protocol: must be http, https, or auto")
ErrInvalidProtocol 协议无效
var ErrInvalidScope = errors.New("invalid token scope: must be host or connect")
ErrInvalidScope 令牌 scope 无效
var ErrInvalidTunnelDescription = errors.New("invalid tunnel description: only Chinese characters, letters, digits, length 0-64")
ErrInvalidTunnelDescription 隧道描述无效
var ErrInvalidTunnelID = errors.New("invalid tunnel ID: must be 8 chars of lowercase letters and digits 2-7")
ErrInvalidTunnelID 隧道 ID 格式无效
var ErrMissingAPIKey = errors.New("missing API key: set it via Config.APIKey or HW_API_KEY env var")
ErrMissingAPIKey 缺少 API Key
var ErrQuotaExceeded = errors.New("account quota exceeded")
ErrQuotaExceeded 配额超限
var ErrTunnelNotFound = errors.New("tunnel not found")
ErrTunnelNotFound 隧道不存在
Functions ¶
func IsAPIError ¶
IsAPIError 判断 error 是否为 APIError,并返回错误码
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client DevBridge SDK 客户端
Example (Connect) ¶
client, err := devbridge.NewClient(devbridge.Config{APIKey: "your-api-key"})
if err != nil {
log.Fatal(err)
}
// 连接隧道,在本地建立端口映射
// 连接成功后,http://localhost:8080 → 远端 Host 的 8080 端口
err = client.Connect(context.Background(), devbridge.ConnectConfig{
TunnelID: "aaaadysa",
Ports: []int{8080},
})
if err != nil {
log.Fatal(err)
}
Example (FullWorkflow) ¶
ctx := context.Background()
// 创建客户端(API Key 也可通过 HW_API_KEY 环境变量设置)
client, err := devbridge.NewClient(devbridge.Config{APIKey: "your-api-key"})
if err != nil {
log.Fatal(err)
}
// 1. 创建隧道
tunnel, err := client.CreateTunnel(ctx, "my-dev-tunnel", "开发联调环境", nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("隧道已创建: %s\n", tunnel.ID)
// 2. 添加端口
allowAnon := true
if err := client.CreatePort(ctx, tunnel.ID, 8080, "http", &allowAnon); err != nil {
log.Fatal(err)
}
// 3. Host 托管(在服务所在设备运行)
//
// 这会阻塞,通常在单独的 goroutine 中运行:
hostCtx, hostCancel := context.WithCancel(context.Background())
go func() {
if err := client.Host(hostCtx, devbridge.HostConfig{
TunnelID: tunnel.ID,
Ports: []int{8080},
}); err != nil {
log.Printf("Host 退出: %v", err)
}
}()
time.Sleep(2 * time.Second) // 等待 Host 就绪
// 4. Connect 连接(在访问设备运行)
//
// 连接成功后,在访问设备上 http://localhost:8080 即可访问远端服务
connectCtx, connectCancel := context.WithCancel(context.Background())
go func() {
if err := client.Connect(connectCtx, devbridge.ConnectConfig{
TunnelID: tunnel.ID,
Ports: []int{8080},
}); err != nil {
log.Printf("Connect 退出: %v", err)
}
}()
time.Sleep(5 * time.Second)
// 5. 清理
connectCancel()
hostCancel()
client.DeleteTunnel(ctx, tunnel.ID)
Example (Host) ¶
client, err := devbridge.NewClient(devbridge.Config{APIKey: "your-api-key"})
if err != nil {
log.Fatal(err)
}
// 查询隧道端口
ports, err := client.ListPorts(context.Background(), "aaaadysa")
if err != nil {
log.Fatal(err)
}
portList := make([]int, len(ports))
for i, p := range ports {
portList[i] = int(p.Port)
}
// 启动 Host(阻塞)
err = client.Host(context.Background(), devbridge.HostConfig{
TunnelID: "aaaadysa",
Ports: portList,
})
if err != nil {
log.Fatal(err)
}
Example (HostWithToken) ¶
client, err := devbridge.NewClient(devbridge.Config{})
if err != nil {
log.Fatal(err)
}
// 先签发 Host 令牌
token, err := client.IssueToken(context.Background(), "aaaadysa", "host")
if err != nil {
log.Fatal(err)
}
// 用令牌启动 Host,不再调用 REST API
err = client.Host(context.Background(), devbridge.HostConfig{
TunnelID: "aaaadysa",
JWTToken: token.Token,
})
if err != nil {
log.Fatal(err)
}
Example (TunnelManagement) ¶
ctx := context.Background()
client, err := devbridge.NewClient(devbridge.Config{APIKey: "your-api-key"})
if err != nil {
log.Fatal(err)
}
// 创建隧道,有效期 24 小时
exp := 24
tunnel, _ := client.CreateTunnel(ctx, "my-tunnel", "描述", &exp)
// 查询隧道列表
tunnels, _ := client.ListTunnels(ctx)
for _, t := range tunnels {
fmt.Printf("%s: %s\n", t.ID, t.Name)
}
// 查询隧道详情
detail, _ := client.ShowTunnel(ctx, tunnel.ID)
fmt.Printf("端口数: %d\n", detail.Status.HostConnectionCount)
// 更新隧道
newName := "renamed-tunnel"
client.UpdateTunnel(ctx, tunnel.ID, &newName, nil, nil)
// 删除隧道
client.DeleteTunnel(ctx, tunnel.ID)
func NewClient ¶
NewClient creates a new SDK client from the given Config. A zero Config is valid; APIKey falls back to HW_API_KEY env var, and other fields fall back to sensible defaults.
最少只需要 API Key:
client, err := devbridge.NewClient(devbridge.Config{
APIKey: "your-api-key",
})
也会自动读取 HW_API_KEY 环境变量:
os.Setenv("HW_API_KEY", "your-key")
client, err := devbridge.NewClient(devbridge.Config{})
func (*Client) Connect ¶
func (c *Client) Connect(ctx context.Context, cfg ConnectConfig) error
Connect 启动 Connect 连接服务
这是一个阻塞方法,在 ctx 被取消或连接彻底断开时返回。 网络短暂中断会自动重连。
基本用法:
err := client.Connect(ctx, devbridge.ConnectConfig{
TunnelID: "aaaadysa",
Ports: []int{8080},
})
使用 API Key 鉴权:
err := client.Connect(ctx, devbridge.ConnectConfig{
TunnelID: "aaaadysa",
APIKey: "your-api-key",
})
使用已有 JWT 令牌:
err := client.Connect(ctx, devbridge.ConnectConfig{
TunnelID: "aaaadysa",
JWTToken: "your-jwt-token",
})
func (*Client) CreatePort ¶
func (c *Client) CreatePort(ctx context.Context, tunnelID string, port int, protocol string, allowAnonymous *bool) error
CreatePort 在隧道上创建端口
allowAnon := true client.CreatePort(ctx, "tunnelId", 8080, "http", &allowAnon)
func (*Client) CreateTunnel ¶
func (c *Client) CreateTunnel(ctx context.Context, name, description string, expiration *int) (*Tunnel, error)
CreateTunnel 创建隧道
client.CreateTunnel(ctx, "my-tunnel", "描述", nil) // 默认有效期 72h exp := 24 client.CreateTunnel(ctx, "my-tunnel", "", &exp) // 24h
func (*Client) DeletePort ¶
DeletePort 删除端口
func (*Client) DeleteTunnel ¶
DeleteTunnel 删除指定隧道
func (*Client) Host ¶
func (c *Client) Host(ctx context.Context, cfg HostConfig) error
Host 启动 Host 托管服务
这是一个阻塞方法,在 ctx 被取消或连接彻底断开时返回。 网络短暂中断会自动重连。
基本用法(已有隧道和端口配置):
err := client.Host(ctx, devbridge.HostConfig{
TunnelID: "aaaadysa",
Ports: []int{8080},
})
使用 API Key 鉴权(跳过令牌签发):
err := client.Host(ctx, devbridge.HostConfig{
TunnelID: "aaaadysa",
APIKey: "your-api-key",
})
使用已有 JWT 令牌(跳过 API 调用):
err := client.Host(ctx, devbridge.HostConfig{
TunnelID: "aaaadysa",
JWTToken: "your-jwt-token",
})
func (*Client) IssueToken ¶
IssueToken 签发隧道令牌
scope 必须是 "host" 或 "connect": token, _ := client.IssueToken(ctx, "tunnelId", "host") // Host 令牌 token, _ := client.IssueToken(ctx, "tunnelId", "connect") // Connect 令牌
func (*Client) ListTunnels ¶
ListTunnels 查询当前工作空间的有效隧道列表
func (*Client) ShowTunnel ¶
ShowTunnel 查询隧道详情
type Config ¶
type Config struct {
// APIKey authenticates REST API requests (X-API-Key header).
// Defaults to HW_API_KEY environment variable.
APIKey string
// APIBaseURL is the REST API base URL.
// Defaults to DefaultAPIBaseURL.
APIBaseURL string
// GatewayAddr is the WebSocket gateway address (host:port).
// Defaults to DefaultGatewayAddr.
GatewayAddr string
// GatewayHost is the WebSocket gateway SNI host.
// Defaults to DefaultGatewayHost.
GatewayHost string
// HTTPClient optionally overrides the HTTP client.
// If nil, a default client with 30s timeout is used.
HTTPClient *http.Client
// StatusWriter receives user-facing status lines (connection progress,
// hosted ports, forwarding info). Defaults to os.Stdout; set it to
// io.Discard to silence these outputs.
StatusWriter io.Writer
}
Config holds the SDK client configuration. A zero Config is valid — missing fields fall back to environment variables and sensible defaults.
type ConnectConfig ¶
type ConnectConfig struct {
TunnelID string // 隧道 ID
Ports []int // 端口列表(为空时从 Host 端通过 SSH 下发)
JWTToken string // JWT 令牌(与 APIKey 二选一)
APIKey string // API Key(与 JWTToken 二选一)
LocalIP string // 本地监听地址,默认 127.0.0.1
// OnReady 在会话就绪(本地端口映射建立)后调用,参数为本次建立的映射列表。
// 每次连接或重连成功都会触发一次。可为 nil。
OnReady func(forwardings []Forwarding)
}
ConnectConfig Connect 连接配置
type Forwarding ¶
Forwarding 端口转发映射信息
type HostConfig ¶
type HostConfig struct {
TunnelID string // 隧道 ID
Ports []int // 本地端口列表(为空时从网关下发)
JWTToken string // JWT 令牌(与 APIKey 二选一)
APIKey string // API Key(与 JWTToken 二选一)
// OnReady 在会话就绪(端口开始转发)后调用,参数为本次托管的端口列表。
// 每次连接或重连成功都会触发一次。可为 nil。
OnReady func(ports []int)
}
HostConfig Host 托管配置
type HostResult ¶
type HostResult struct {
TunnelID string // 隧道 ID
Ports []int // 实际托管的端口
TunnelURL string // 隧道访问地址
}
HostResult Host 运行结果信息
type Limits ¶
type Limits struct {
ResetAt int64 `json:"resetAt"`
QuotaBytes int64 `json:"quotaBytes"`
RemainingBytes int64 `json:"remainingBytes"`
ActiveTunnels int64 `json:"activeTunnels"`
MaxTunnels int32 `json:"maxTunnels"`
MaxPortsPerTunnel int32 `json:"maxPortsPerTunnel"`
MaxHostsPerTunnel int32 `json:"maxHostsPerTunnel"`
MaxTunnelBandwidthBytesPerSecond int64 `json:"maxTunnelBandwidthBytesPerSecond"`
MaxHTTPRequestsPerMinutePerPort int32 `json:"maxHttpRequestsPerMinutePerPort"`
MaxConnectionsPerPort int32 `json:"maxConnectionsPerPort"`
}
Limits 配额
type Port ¶
type Port struct {
TunnelID string `json:"tunnelId"`
Port int32 `json:"port"`
Protocol string `json:"protocol"` // http, https, auto
AllowAnonymous bool `json:"allowAnonymous"` // 是否允许匿名访问
}
Port 端口配置
type Tunnel ¶
type Tunnel struct {
ID string `json:"tunnelId"` // 隧道 ID,8 位小写 Base32
Name string `json:"name"` // 隧道名称
Description string `json:"description"` // 隧道描述
ExpirationHours int `json:"expirationHours"` // 有效期(小时)
TunnelExpiration uint32 `json:"tunnelExpiration"` // 隧道过期时间(Unix 秒)
PortCount int `json:"portCount"` // 端口数量
}
Tunnel 隧道
type TunnelDetail ¶
type TunnelDetail struct {
Name string `json:"name"`
ID string `json:"tunnelId"`
TunnelExpiration uint32 `json:"tunnelExpiration"` // Unix 秒
Description string `json:"description"`
Status *TunnelStatus `json:"status,omitempty"`
}
TunnelDetail 隧道详情(含状态)
type TunnelStatus ¶
type TunnelStatus struct {
ClientConnectionCount int `json:"clientConnectionCount"` // Connect 连接数
HostConnectionCount int `json:"hostConnectionCount"` // Host 连接数
TotalUploadBytes int64 `json:"totalUploadBytes"` // 上行字节
TotalDownloadBytes int64 `json:"totalDownloadBytes"` // 下行字节
}
TunnelStatus 隧道运行状态
type TunnelToken ¶
type TunnelToken struct {
TunnelID string `json:"tunnelId"`
Scope string `json:"scope"` // host 或 connect
Token string `json:"token"` // JWT 令牌
}
TunnelToken 隧道令牌
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
connect-service
command
Command connect-service 是服务 B:建立远程连接并验证访问服务 A 的本地服务。
|
Command connect-service 是服务 B:建立远程连接并验证访问服务 A 的本地服务。 |
|
host-service
command
Command host-service 是服务 A:启动本地 HTTP 服务并创建托管。
|
Command host-service 是服务 A:启动本地 HTTP 服务并创建托管。 |
|
verify
command
Command verify 用 SDK 托管本地服务,打印隧道公网 URL 供浏览器访问。
|
Command verify 用 SDK 托管本地服务,打印隧道公网 URL 供浏览器访问。 |