Android设备上的ktor websocket安装错误

Posted

技术标签:

【中文标题】Android设备上的ktor websocket安装错误【英文标题】:ktor websocket install error on Android device 【发布时间】:2020-11-26 09:13:03 【问题描述】:

我正在尝试在带有 ktor websocket 的 android 设备上运行简单的聊天示例,但效果不佳。 在 MainActivity 中安装 websocket 服务器时出现错误

这里是 ktor websocket 的 build.gradle

//this is for project
ext.ktor_version = '1.2.5'
maven  url "https://dl.bintray.com/kotlin/ktor" 

//this is for app
 packagingOptions 
        exclude 'META-INF/*'
    

    implementation "io.ktor:ktor-websockets:$ktor_version"

这是 MainActivity 的代码

import io.ktor.application.*
import io.ktor.features.*
import io.ktor.http.cio.websocket.*
import io.ktor.http.cio.websocket.CloseReason
import io.ktor.http.cio.websocket.Frame
import io.ktor.http.content.*
import io.ktor.routing.*
import io.ktor.sessions.*
import io.ktor.util.*
import io.ktor.websocket.*
import kotlinx.coroutines.channels.*
import java.time.*

class MainActivity : AppCompatActivity() 

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        install(WebSockets) 
            pingPeriod = Duration.ofSeconds(60) // Disabled (null) by default
            timeout = Duration.ofSeconds(15)
            maxFrameSize = Long.MAX_VALUE // Disabled (max value). The connection will be closed if surpassed this length.
            masking = false
        
    

当我在 Android Studio 上构建这段代码时,发生了错误

public fun <P : Pipeline<*, ApplicationCall>, B : Any, F : Any> ???.install(feature: ApplicationFeature<???, WebSockets.WebSocketOptions, WebSockets>, configure: WebSockets.WebSocketOptions.() -> Unit = ...): WebSockets defined in io.ktor.application

【问题讨论】:

【参考方案1】:

Websockets 是可以插入应用程序的服务器features 之一,因此install 调用的上下文应该是Ktor 应用程序,而不是Android Activity。我建议您查看Hello world 示例。这是您修改的示例代码:

import io.ktor.application.*
import io.ktor.http.cio.websocket.*
import io.ktor.server.engine.*
import io.ktor.websocket.*
import java.time.Duration
import io.ktor.routing.*
import io.ktor.server.netty.*

class MainActivity : AppCompatActivity() 
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        embeddedServer(Netty, 4444) 
            install(WebSockets) 
                pingPeriod = Duration.ofSeconds(60) // Disabled (null) by default
                timeout = Duration.ofSeconds(15)
                maxFrameSize = Long.MAX_VALUE // Disabled (max value). The connection will be closed if surpassed this length.
                masking = false
            
            routing 
                webSocket("/") 
                    // ...
                
            
        .start()
    

您需要添加以下依赖项才能使此示例正常工作:

implementation "io.ktor:ktor-server-core:$ktor_version"
implementation "io.ktor:ktor-server-netty:$ktor_version"
implementation "ch.qos.logback:logback-classic:1.2.3" // for logging

【讨论】:

有效!但不幸的是,只有 websocket 连接运行良好。路由似乎不起作用。当我用js检查浏览器时,连接到Android设备中的websocket服务器后没有回复回显消息。你知道为什么吗? 这里是路由代码routing webSocket("/") println("webSocket OK") while (true) val frame = incoming.receive() when (frame) is Frame.Text -&gt; val text = frame.readText() outgoing.send(Frame.Text(text)) 这里是js代码&lt;script type = "text/javascript"&gt; function startWebSocket() if ("WebSocket" in window) var ws = new WebSocket("ws://192.168.0.7:4444"); ws.onopen = function() ws.send("Hello"); alert("Send message to Server(Hello)."); ; ws.onmessage = function (evt) var msg = evt.data; alert("Message is received(" + msg + ")"); ; ws.onclose = function() alert("WebSocket is closed."); ; else alert("Your browser does not support WebSocket !!!"); &lt;/script&gt; 请尝试来自here 的代码示例。此外,请尝试指定 IP 地址127.0.0.1(如果您是在设备或模拟器的浏览器中测试它)而不是192.168.0.7。在您的代码示例中,我没有看到您调用 startWebSocket 函数,所以这也可能是一个问题。 你能分享你的应用吗?我想和 ktor 建立聊天,但什么都编译不了【参考方案2】:

能否请您介绍一下您当前使用的 Kotlin 版本和 Gradle 版本?如果 Kotlin 版本小于 1.4,那么我建议尝试将 -jvm-android 添加到 build.gradle 中的 ktor 依赖项名称中。

【讨论】:

我的 Kotlin 版本是 '1.3.61' 但我不知道如何在 build.gradle 中添加 -android 依赖项。当我将 build.gradle 更改为 ext.kotlin_version = '1.3.61' -android 时,会发生构建错误。 Could not get unknown property 'android' for object of type org.gradle.api.internal.initialization.DefaultScriptHandler.

以上是关于Android设备上的ktor websocket安装错误的主要内容,如果未能解决你的问题,请参考以下文章

Android 和 iOS 上的 websocket

Ktor Websocket 功能与 ktor 中的 ContentNeogation 功能 (JSON / GSON)

将自定义标头设置为 websocket 请求 (ktor)

尝试在客户端接收数据时,Ktor-websocket 库不执行任何操作

Ktor websockets 身份验证

如何保持 Kotlin Ktor websocket 处于打开状态