refactor(rpc): 重构 RPC 客户端并添加重连机制

- 更新了 RPC 客户端的初始化和重连逻辑
- 添加了重连函数和最大重试次数的配置
- 优化了与服务器的连接管理
- 调整了端口相关的数据类型
This commit is contained in:
2025-07-17 05:20:30 +08:00
parent b6231f6eb9
commit bf72b91fc6
18 changed files with 131 additions and 46 deletions

View File

@@ -323,6 +323,7 @@ func websocketClient(ctx context.Context, addr string, namespace string, outs []
requests: requests,
stop: stop,
exiting: exiting,
reconfun: config.reconnfun,
}
go func() {

View File

@@ -32,6 +32,7 @@ type Config struct {
proxyConnFactory func(func() (*websocket.Conn, error)) func() (*websocket.Conn, error) // for testing
methodNamer MethodNameFormatter
reconnfun func()
}
func defaultConfig() Config {
@@ -100,6 +101,11 @@ func WithClientHandler(ns string, hnd interface{}) func(c *Config) {
c.reverseHandlers = append(c.reverseHandlers, clientHandler{ns, hnd})
}
}
func WithReconnFun(s func()) func(c *Config) {
return func(c *Config) {
c.reconnfun = s
}
}
// WithClientHandlerAlias creates an alias for a client HANDLER method - for handlers created
// with WithClientHandler

View File

@@ -61,6 +61,7 @@ type wsConn struct {
stopPings func()
stop <-chan struct{}
exiting chan struct{}
reconfun func()
// incoming messages
incoming chan io.Reader
@@ -661,6 +662,7 @@ func (c *wsConn) tryReconnect(ctx context.Context) bool {
c.writeLk.Unlock()
go c.nextMessage()
c.reconfun()
}()
return true
@@ -789,6 +791,7 @@ func (c *wsConn) handleWsConn(ctx context.Context) {
log.Debugw("websocket error", "error", err, "lastAction", action, "time", time.Since(start))
// only client needs to reconnect
if !c.tryReconnect(ctx) {
return // failed to reconnect
}
@@ -938,3 +941,34 @@ func normalizeID(id interface{}) (interface{}, error) {
return nil, xerrors.Errorf("invalid id type: %T", id)
}
}
// Retry 执行带指数退避的重试
// 参数:
// - baseDelay: 基础延迟时间
// - maxRetries: 最大重试次数
// - fn: 需要执行的函数返回bool表示是否成功error为具体错误
//
// 返回:
// - 最后一次错误(如果所有重试都失败)
func Retry(baseDelay time.Duration, maxRetries int, fn func() (bool, error)) error {
var lastErr error
for i := 0; i <= maxRetries; i++ {
if i > 0 {
// 计算当前重试的延迟时间(指数增长)
delay := baseDelay * time.Duration(1<<i)
fmt.Printf("重试 %d/%d: 将在 %v 后重试,上次错误: %v", i, maxRetries, delay, lastErr)
time.Sleep(delay)
}
// 执行函数
success, err := fn()
if success {
return nil // 成功返回nil
}
lastErr = err // 记录错误,用于后续重试失败时返回
}
return fmt.Errorf("达到最大重试次数 (%d),最后错误: %w", maxRetries, lastErr)
}