当应用程序在 Tinder/Scarlet Websocket 中进入后台时保持 websocket 打开

Posted

技术标签:

【中文标题】当应用程序在 Tinder/Scarlet Websocket 中进入后台时保持 websocket 打开【英文标题】:keep websocket open when app goes background in Tinder/Scarlet Websocket 【发布时间】:2021-11-04 11:58:54 【问题描述】:

在 Jetpack Compose (1.0.4) 中,我使用 Tinder/Scarlet(2.4.0) 连接 WebSocket

implementation 'com.github.Tinder.Scarlet:scarlet:0.2.4'
implementation 'com.github.Tinder.Scarlet:scarlet-lifecycle-android:0.2.4'
implementation 'com.github.Tinder.Scarlet:scarlet-message-adapter-moshi:0.2.4'
implementation 'com.github.tinder.scarlet:scarlet-protocol-websocket-okhttp:0.2.4'

这就是我如何初始化和描述它的方式

@Provides
    fun providesApplication(@ApplicationContext context: Context): MyApplication
        return context as MyApplication
    



@Provides
    fun provideScarlet(
        application: MyApplication,
        client: OkHttpClient,
        moshi: Moshi
    ): Scarlet 
        val protocol = OkHttpWebSocket(
            client,
            OkHttpWebSocket.SimpleRequestFactory(
                 Request.Builder().url(baseWebSocketAddress).build() ,
                 ShutdownReason.GRACEFUL 
            )
        )

        val scarletConfiguration = Scarlet.Configuration(
            messageAdapterFactories = listOf(MoshiMessageAdapter.Factory(moshi)),
            streamAdapterFactories = listOf(FlowStreamAdapter.Factory()),
            backoffStrategy = LinearBackoffStrategy(500),
            lifecycle = AndroidLifecycle.ofApplicationForeground(
                application
            )
        )
        return Scarlet(protocol, scarletConfiguration)
    

@Singleton
@Provides
fun provideScarletMessagingService(scarlet: Scarlet): ScarletMessagingService 
    return scarlet.create()

一切正常,包括事件、观察消息和其他问题,当我关闭/最小化应用程序时,websocket 即使在实现时也会关闭:

   backoffStrategy = LinearBackoffStrategy(500),
   lifecycle = AndroidLifecycle.ofApplicationForeground(
        application
    )

我正在像这样在我的视图模型上使用猩红色实例

@HiltViewModel
class MessagesViewModel
@Inject constructor(
    private val scarletMessagingService: ScarletMessagingService) : ViewModel() 
       init 
            scarletMessagingService.observeMessage()
        .flowOn(Dispatchers.IO)
        .onEach 
            Timber.d("A message from server $it.toString()")
        
        .launchIn(viewModelScope)
       

我也有这个权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

【问题讨论】:

它是如何连接到 Jetpack Compose 的?我猜你没有提供最重要的代码。 @Jakoss 我更新了视图模型的其余部分并且效果很好,我认为其余的代码并不重要,我只想说我在 jetpack compose 中构建了我的项目仍然没有尝试在视图中显示消息 我猜关于 compose 的信息只是你问题中不必要的噪音,我会考虑删除它 【参考方案1】:

前台服务权限并不是您的应用现在可以在后台运行的神奇开关。您必须实际实现服务并将其作为前台运行。在该服务中,您必须实现对 websocket 的实际处理。

您可以在官方文档中了解如何实现它:https://developer.android.com/guide/components/foreground-services

【讨论】:

我猜它不是最好的解决方案,因为 Tinder 已经开发了它,看看medium.com/tinder-engineering/… 这是唯一的解决方案,Tinder 唯一做的就是与 android 生命周期集成。您应该将连接绑定到您必须创建的服务生命周期(这也是 android 生命周期)

以上是关于当应用程序在 Tinder/Scarlet Websocket 中进入后台时保持 websocket 打开的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序处于后台 FCM 中时更新 Web 应用程序用户界面

当同时使用 GraphQL 时,Nodejs 和 Express 在 MERN 堆栈 Web 应用程序中的作用是啥?

当 web 端口 80 已经在使用时,如何监听 heroku 上的任何端口?

当 Web 应用程序进行维护时,重定向的最佳位置是啥?

当一个 MVC Web 应用程序托管在多个用户同时访问的服务器上时,应用程序和会话变量会发生啥?

当用户从托管在 Digital Ocean 上的 Web 应用程序将图像上传到 AWS S3 时,是出站还是入站带宽传输?