refactor(rpc): 重构 RPC 客户端并添加重连机制
- 更新了 RPC 客户端的初始化和重连逻辑 - 添加了重连函数和最大重试次数的配置 - 优化了与服务器的连接管理 - 调整了端口相关的数据类型
This commit is contained in:
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user