如何在 SocketIO 中使用 Hilt 中最新的 accessToken?

问题描述 投票:0回答:1

我正在使用 Hilt 并实现套接字。

这是用于创建存储库的存储库模块。

@Module
@InstallIn(SingletonComponent::class)
object RepositoryModule {
    @Provides
    fun provideSocketRepository(socket: Socket): SocketRepository {
        return SocketRepository(socket)
    }
}

这是将 Socket 注入 SocketRepository 的 ServiceModule。

@Module
@InstallIn(SingletonComponent::class)
object ServiceModule {
    @Provides
    fun provideSocket(): Socket {
        logd("socket: accessToken: ${Common.accessToken}")
        val options = IO.Options().apply {
            timeout = 30000
            reconnection = true
            reconnectionDelay = 1000
            reconnectionAttempts = 300
            transports = arrayOf(WebSocket.NAME)
            extraHeaders = mapOf(
                "Authorization" to listOf("Bearer ${Common.accessToken}"),
                "Content-Type" to listOf("application/json"),
                "identity" to listOf("app")
            )
        }
        return IO.socket(UrlType.BACK_OFFICE_SERVER.getUrl(), options)
    }
}

问题是

  1. Common.accessToken
    是全局变量,需要重构,并且在登录后更新。但是,整个应用程序进程全局需要Socket。所以,时间是注射后。如何使用hilt获取最新的accessToken?

  2. 我应该在某些时候以编程方式连接和断开套接字。如果我使用 hilt,它将继续注入到 repo 类中。当我尝试断开连接时,实例是否还活着?例如,

    socket.disconnect
    没有
    socket = null
    ,然后
    socket.connect
    在需要连接时重新连接套接字。

android kotlin sockets socket.io dagger-hilt
1个回答
0
投票

在您的情况下,不应注入

Socket
,而是将其包装在 Manager 类中,该类将处理逻辑并注入到存储库中。

您可以有一个单例

AuthManager
类来控制登录和令牌流(您可以自己定义模块):

class AuthManager @Inject constructor() {
    val token = MutableStateFlow<String?>(null)

    suspend fun signIn() {
        // Do sign in stuff, then update your token
        token.emit(newToken)
    }
}

然后你的

SocketManager
类有
AuthManager
作为依赖项:

class SocketManager @Inject constructor(authManager: AuthManager) {
    val socket = MutableStateFlow<Socket?>(null)

    init {
        authManager.token.collect {
            // Token updated, recreated your socket here and emit new socket to collector
            socket.emit or socket.trySend
        }
    }
}

SocketManager
也是Singleton(你可以自己定义Module)

最后,在您想要使用套接字的任何地方,例如

Activity
,注入
SocketManager
并根据需要收集套接字:

@AndroidEntryPoint
class MyActivity: AppCompatActivity {
    @Inject
    lateinit var socketManager: SocketManager

    fun onCreate() {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                socketManager.socket.collect {
                    // Use your socket here, socket will be changed after token changed and this code block is called
                }
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.