Android开发实战班 - 网络编程 - WebSocket 实时通信

在现代应用开发中,实时通信是许多应用的核心功能之一,例如聊天应用、实时通知、在线游戏等。WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,能够实现服务器与客户端之间的实时双向数据交换。相比于传统的 HTTP 请求,WebSocket 更加高效,适合实时数据传输。本章节将介绍 WebSocket 的基本概念、优势、在 Android 中的实现方式以及实战案例,帮助学员掌握 WebSocket 实时通信的实现。

20.1 WebSocket 简介

  • 什么是 WebSocket:

    • WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。
    • WebSocket 允许服务器主动向客户端推送数据,实现实时双向通信。
  • WebSocket 的特点:

    • 全双工通信: 服务器和客户端可以同时发送和接收数据。
    • 实时性: WebSocket 实现了真正的实时通信,适合实时数据传输。
    • 高效性: WebSocket 使用单个 TCP 连接,减少了 HTTP 请求的开销。
    • 支持跨域: WebSocket 支持跨域通信,可以在不同域名之间进行通信。
  • WebSocket 的使用场景:

    • 实时聊天应用
    • 实时通知
    • 在线游戏
    • 实时数据监控
    • 实时协作应用

20.2 WebSocket 与 HTTP 的比较

特性 WebSocket HTTP
连接方式 单个 TCP 连接,全双工通信 短连接,每次请求都需要重新建立连接
实时性 实时双向通信 请求-响应模式,非实时
效率 高效,减少连接开销 每次请求都需要重新建立连接,效率较低
数据格式 文本或二进制数据 文本数据(通常是 JSON, XML 等)
支持协议 WebSocket 协议 HTTP 协议
适用场景 实时通信 静态资源加载、数据查询等

20.3 WebSocket 在 Android 中的实现

在 Android 中,可以使用 OkHttp 提供的 WebSocket 支持来实现 WebSocket 通信。OkHttp 提供了简洁的 API,可以方便地创建 WebSocket 连接、发送消息、接收消息等。

20.3.1 添加 OkHttp 依赖

build.gradle 文件中添加 OkHttp 依赖:

groovy 复制代码
dependencies {
    implementation "com.squareup.okhttp3:okhttp:4.9.3"
}
20.3.2 创建 WebSocket 连接

使用 OkHttp 创建 WebSocket 连接,并处理连接、消息、关闭和错误事件。

kotlin 复制代码
import okhttp3.*
import okio.ByteString

class WebSocketManager {

    private val client = OkHttpClient()
    private val request = Request.Builder()
        .url("wss://echo.websocket.org")
        .build()

    private val listener = object : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            super.onOpen(webSocket, response)
            println("WebSocket 连接已打开")
            // 发送消息
            webSocket.send("Hello, WebSocket!")
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            println("收到消息: $text")
        }

        override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
            super.onMessage(webSocket, bytes)
            println("收到二进制消息: ${bytes.hex()}")
        }

        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosing(webSocket, code, reason)
            println("WebSocket 连接正在关闭: $code, $reason")
            webSocket.close(1000, null)
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            println("WebSocket 连接失败: ${t.message}")
        }
    }

    fun connect() {
        client.newWebSocket(request, listener)
    }

    fun sendMessage(message: String) {
        client.dispatcher.executorService.execute {
            client.webSocket(request, listener).send(message)
        }
    }

    fun close() {
        client.dispatcher.executorService.execute {
            client.close(1000, "Goodbye")
        }
    }
}
20.3.3 使用 WebSocket

在 Activity 或 Fragment 中使用 WebSocketManager 进行 WebSocket 连接、发送消息和关闭连接。

kotlin 复制代码
class WebSocketActivity : AppCompatActivity() {

    private lateinit var webSocketManager: WebSocketManager

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

        webSocketManager = WebSocketManager()
        webSocketManager.connect()

        findViewById<Button>(R.id.buttonSend).setOnClickListener {
            val message = findViewById<EditText>(R.id.editTextMessage).text.toString()
            webSocketManager.sendMessage(message)
        }

        findViewById<Button>(R.id.buttonClose).setOnClickListener {
            webSocketManager.close()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        webSocketManager.close()
    }
}

20.4 WebSocket 实战案例

  1. 案例一:使用 WebSocket 实现实时聊天应用

    • 使用 OkHttp 创建 WebSocket 连接。
    • 发送和接收消息。
    • 在 Activity 中显示聊天消息。
    kotlin 复制代码
    class ChatActivity : AppCompatActivity() {
    
        private lateinit var webSocketManager: WebSocketManager
        private lateinit var chatAdapter: ChatAdapter
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_chat)
    
            chatAdapter = ChatAdapter()
            val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
            recyclerView.adapter = chatAdapter
            recyclerView.layoutManager = LinearLayoutManager(this)
    
            webSocketManager = WebSocketManager()
            webSocketManager.connect()
    
            webSocketManager.listener = object : WebSocketListener() {
                override fun onMessage(webSocket: WebSocket, text: String) {
                    super.onMessage(webSocket, text)
                    runOnUiThread {
                        chatAdapter.addMessage(text)
                        recyclerView.scrollToPosition(chatAdapter.itemCount - 1)
                    }
                }
            }
    
            findViewById<Button>(R.id.buttonSend).setOnClickListener {
                val message = findViewById<EditText>(R.id.editTextMessage).text.toString()
                webSocketManager.sendMessage(message)
                chatAdapter.addMessage(message)
                recyclerView.scrollToPosition(chatAdapter.itemCount - 1)
            }
        }
    
        override fun onDestroy() {
            super.onDestroy()
            webSocketManager.close()
        }
    }
  2. 案例二:使用 WebSocket 实现实时通知

    • 使用 OkHttp 创建 WebSocket 连接。
    • 接收服务器推送的实时通知。
    • 在通知栏显示通知。

20.5 课后作业

  1. 任务一:使用 WebSocket 实现实时聊天应用

    • 使用 OkHttp 创建 WebSocket 连接。
    • 发送和接收消息。
    • 在 Activity 中显示聊天消息。
  2. 任务二:使用 WebSocket 实现实时通知

    • 使用 OkHttp 创建 WebSocket 连接。
    • 接收服务器推送的实时通知。
    • 在通知栏显示通知。
相关推荐
_李小白4 分钟前
【Android 美颜相机】第一天:认识Android-GPUImage项目
android·数码相机
Mr -老鬼17 分钟前
谷歌安卓文档查询建议:优先使用英语页面的原因及实践指南
android
深圳南柯电子17 分钟前
深圳南柯电子|EMC电磁兼容测试系统:5G时代应对频段的干扰挑战
网络·人工智能·互联网·实验室·emc
w陆压24 分钟前
2.TCP三次握手、四次挥手
网络·网络协议·计网知识点
2501_9151063230 分钟前
常见 iOS 抓包工具的使用方式与组合思路
android·ios·小程序·https·uni-app·iphone·webview
知乎的哥廷根数学学派31 分钟前
基于高阶统计量引导的小波自适应块阈值地震信号降噪算法(MATLAB)
网络·人工智能·pytorch·深度学习·算法·机器学习·matlab
DeepFlow 零侵扰全栈可观测32 分钟前
DeepFlow 实践:利用 eBPF 实现覆盖从网关到数据库的全栈分布式追踪
网络·分布式·云原生·云计算
松涛和鸣35 分钟前
51、51单片机
c语言·网络·单片机·嵌入式硬件·tcp/ip·51单片机
鹏程十八少42 分钟前
1.Android 3分钟跑通腾讯 Shadow 插件化官方Demo:零反射、手把手实战(基于源码依赖)
android·前端·面试
似霰42 分钟前
HIDL Hal 开发笔记8----添加硬件访问服务
android·framework·hal