Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin Google pubsub emulator不断推送相同的消息?_Kotlin_Google Cloud Pubsub_Google Cloud Pubsub Emulator - Fatal编程技术网

Kotlin Google pubsub emulator不断推送相同的消息?

Kotlin Google pubsub emulator不断推送相同的消息?,kotlin,google-cloud-pubsub,google-cloud-pubsub-emulator,Kotlin,Google Cloud Pubsub,Google Cloud Pubsub Emulator,我正在构建一个测试库,它提取了一些第三方资源,比如GooglePubSub 问题是,当我创建一个主题和订阅时,消息会不断到达。示例输出: 确认id:“projects/test-project-123/subscriptions/my subscription:2” 消息{data:“我的消息!-1”消息id:“2”发布时间{ 秒:1614597484} 确认id:“projects/test-project-123/subscriptions/my subscription:4” 消息{dat

我正在构建一个测试库,它提取了一些第三方资源,比如GooglePubSub

问题是,当我创建一个主题和订阅时,消息会不断到达。示例输出:

确认id:“projects/test-project-123/subscriptions/my subscription:2” 消息{data:“我的消息!-1”消息id:“2”发布时间{ 秒:1614597484}

确认id:“projects/test-project-123/subscriptions/my subscription:4” 消息{data:“我的消息!-1”消息id:“2”发布时间{ 秒:1614597484}

奇怪的是,出版时间是一样的

提取消息的代码:

fun poll(size: Int, subscriptionId: String): List<String> {
    val subscriberStubSettings: SubscriberStubSettings = SubscriberStubSettings.newBuilder()
        .setTransportChannelProvider(channelProvider)
        .setCredentialsProvider(credentialsProvider)
        .build()
    GrpcSubscriberStub.create(subscriberStubSettings).use { subscriber ->
        val pullRequest: PullRequest = PullRequest.newBuilder()
            .setMaxMessages(size)
            .setSubscription(ProjectSubscriptionName.format(projectId, subscriptionId))
            .build()
        val pullResponse: PullResponse = subscriber.pullCallable().call(pullRequest)


        val acknowledgeRequest = AcknowledgeRequest.newBuilder()
            .setSubscription(ProjectSubscriptionName.format(projectId, subscriptionId))
            .addAllAckIds(
                pullResponse.receivedMessagesList
                    .stream()
                    .map { it.ackId }.toList()
            ).build()

        return pullResponse.receivedMessagesList
            .map { it.message.data.toStringUtf8() }
            .toList()
    }
}
额外功能:

private val channelProvider: TransportChannelProvider
    get() {
        return FixedTransportChannelProvider
            .create(
                GrpcTransportChannel.create(channel())
            )
    }

private fun channel(): ManagedChannel {
    return if (channels.isEmpty()) {
        val endpoint = emulator.emulatorEndpoint
        val channel = ManagedChannelBuilder
            .forTarget(endpoint)
            .usePlaintext()
            .build()
        channels.add(channel)
        channel
    } else {
        channels.first()
    }
}

var emulator: PubSubEmulatorContainer = PubSubEmulatorContainer(
        DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:latest")
    )
我怎样才能克服它?这是一个bug,还是我做错了什么?

您的代码应该确认您已经收到(并且大概已经处理)了每条消息:

消息发送给订户后,订户应确认消息。消息一旦发送出去交付,在订户确认之前,即被视为未完成。发布/订阅将重复尝试传递任何尚未确认的消息。()


这些重复的尝试就是你在这里看到的,所以看起来确认没有发生。尝试RPC调用。

您是在通过循环的每次调用中立即收到重复消息,还是在一段时间后收到重复消息?确认消息的代码在哪里?它会在一段时间后重复,因此我假设消息不会得到确认和重新传递。我用重新交付机制更新了代码。你知道如何使用模拟器吗?我找不到任何示例。您编辑的代码创建了一个AcknowledgerRequest,但实际上它并没有在任何地方使用。有一个Java示例;重要的一行是subscriber.acknowledgeCallable()调用(acknowledgeRequest)。还请注意,通常情况下,您会在处理完每条消息后确认已对其进行了处理,因此根据其余代码的外观,这可能比调用
poll
要晚。在本例中,由于您实际上没有对消息做任何处理,因此立即确认消息是可以的。Thx,您帮了我很多忙!
private val channelProvider: TransportChannelProvider
    get() {
        return FixedTransportChannelProvider
            .create(
                GrpcTransportChannel.create(channel())
            )
    }

private fun channel(): ManagedChannel {
    return if (channels.isEmpty()) {
        val endpoint = emulator.emulatorEndpoint
        val channel = ManagedChannelBuilder
            .forTarget(endpoint)
            .usePlaintext()
            .build()
        channels.add(channel)
        channel
    } else {
        channels.first()
    }
}

var emulator: PubSubEmulatorContainer = PubSubEmulatorContainer(
        DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:latest")
    )