Android App创建websocket server,App创建websocket服务器,App连接websocket

酆君墨
2023-12-01

使用okhttp连接websocket

1、引入okhttp库

implementation 'com.squareup.okhttp3:okhttp:3.11.0'

2、布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3、需要用到的权限

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

4、如果使用的URL是 本地app服务创建的websocket,那么只需在 AndroidManifest.xml 的 <application> 标记中添加这一行,要不然运行有错误的安全性提醒。

android:usesCleartextTraffic="true"

5、okhttp 连接websocket主要代码

class MainActivity : AppCompatActivity() {

    companion object {
        const val TAG = "MainActivity"
    }

    private lateinit var binding: ActivityMainBinding
    private lateinit var client: OkHttpClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        client = OkHttpClient()
        binding.tvHelloWorld.setOnClickListener {
            val request = Request.Builder().url("ws://192.168.3.104:8080/chat").build()
            val webSocketListenerCoinPrice: WebSocketListener = object : WebSocketListener() {
                override fun onOpen(webSocket: WebSocket, response: Response) {
                    webSocket.send("hello world")
                    Log.e(TAG, "onOpen")
                }

                override fun onMessage(webSocket: WebSocket, text: String) {
                    Log.e(TAG, "MESSAGE: $text")
                }

                override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                    Log.e(TAG, "MESSAGE: " + bytes.hex())
                }

                override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                    webSocket.close(1000, null)
                    webSocket.cancel()
                    Log.e(TAG, "CLOSE: $code $reason")
                }

                override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                    Log.e(TAG, "CLOSED: $code $reason")
                }

                override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                    t.printStackTrace()
                    Log.e(TAG, "dd:" + response?.message())
                }
            }
            client.newWebSocket(request, webSocketListenerCoinPrice)
            client.dispatcher().executorService().shutdown()
        }
    }

}

使用Ktor创建websocket server

1、导入Ktor库

implementation 'io.ktor:ktor-server-cio:1.6.8'
implementation 'io.ktor:ktor-websockets:1.6.8'

2、新建application,使用Ktor创建websocket服务端

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        embeddedServer(CIO, 8080) {
            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 {
                get("/") {
                    call.respondText("Hello, world!")
                }

                webSocket("/echo") {
                    send("Please enter your name")
                    for (frame in incoming) {
                        when (frame) {
                            is Frame.Text -> {
                                val receivedText = frame.readText()
                                if (receivedText.equals("bye", ignoreCase = true)) {
                                    close(CloseReason(CloseReason.Codes.NORMAL, "Client said BYE"))
                                } else {
                                    send(Frame.Text("Hi, $receivedText!"))
                                    
                                }
                            }
                            else -> {}
                        }
                    }
                }

                val connections = Collections.synchronizedSet<Connection?>(java.util.LinkedHashSet())
                webSocket("/chat") {
                    val thisConnection = Connection(this)
                    connections += thisConnection
                    send("You've logged in as [${thisConnection.name}]")

                    for (frame in incoming) {
                        when (frame) {
                            is Frame.Text -> {
                                val receivedText = frame.readText()
                                val textWithUsername = "[${thisConnection.name}]: $receivedText"
                                connections.forEach {
                                    it.session.send(textWithUsername)
                                }
                            }
                            else -> {}
                        }
                    }
                }
            }

        }.start()


    }
}
class Connection(val session: DefaultWebSocketSession) {
    companion object {
        var lastId = AtomicInteger(0)
    }

    val name = "user${lastId.getAndIncrement()}"
}

或者不适用okhttp直接使用ktor连接websocket

导入Ktor client端引用库

implementation("io.ktor:ktor-client-websockets:1.6.8")
implementation("io.ktor:ktor-client-cio:1.6.8")
class KtorActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        val client = HttpClient {
            install(WebSockets)
        }
        runBlocking {
            client.webSocket(method = HttpMethod.Get, host = "127.0.0.1", port = 8080, path = "/chat") {
                while(true) {
                    val othersMessage = incoming.receive() as? Frame.Text ?: continue
                    println(othersMessage.readText())
                    val myMessage = readLine()
                    if(myMessage != null) {
                        send(myMessage)
                    }
                }
            }
        }
        client.close()
        println("Connection closed. Goodbye!")
    }
}

 类似资料: