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()
}
}
}
1、导入Ktor库
implementation 'io.ktor:ktor-server-cio:1.6.8'
implementation 'io.ktor:ktor-websockets:1.6.8'
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()}"
}
导入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!")
}
}