Android Nomad #37 - Real-time Communication in Android
HTTP Polling vs WebSockets vs Server-Sent Events
In the world of mobile app development, real-time communication between client and server is crucial for creating responsive and dynamic applications. Android developers have several options to implement this functionality. In this blog post, we'll explore three popular methods: HTTP polling, WebSockets, and Server-Sent Events (SSE). We'll discuss their differences and provide simple code snippets to demonstrate their usage in Android.
1. HTTP Polling
HTTP polling is a technique where the client periodically sends requests to the server to check for new data. It's simple to implement but can be inefficient for frequent updates.
Pros:
- Easy to implement
- Works with standard HTTP requests
- Compatible with older servers
Cons:
- Inefficient for frequent updates
- Increased server load
- Higher latency
Code Example:
import android.os.Handler
import android.os.Looper
import okhttp3.*
import java.io.IOException
class HttpPollingExample {
private val client = OkHttpClient()
private val handler = Handler(Looper.getMainLooper())
private val pollingInterval = 5000L // 5 seconds
fun startPolling() {
handler.post(object : Runnable {
override fun run() {
pollServer()
handler.postDelayed(this, pollingInterval)
}
})
}
private fun pollServer() {
val request = Request.Builder()
.url("https://api.example.com/data")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// Handle error
}
override fun onResponse(call: Call, response: Response) {
// Process the response
val responseData = response.body?.string()
// Update UI or process data
}
})
}
}2. WebSockets
WebSockets provide a full-duplex, bidirectional communication channel between client and server. They're efficient for real-time updates and allow both client and server to send messages at any time.
Pros:
- Real-time, bidirectional communication
- Efficient for frequent updates
- Reduced latency
Cons:
- More complex to implement
- Requires WebSocket support on the server
- May require additional infrastructure for scaling
Code Example:
import okhttp3.*
import okio.ByteString
class WebSocketExample {
private lateinit var webSocket: WebSocket
fun connectWebSocket() {
val client = OkHttpClient()
val request = Request.Builder()
.url("ws://websocket.example.com")
.build()
webSocket = client.newWebSocket(request, object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
// Connection opened
}
override fun onMessage(webSocket: WebSocket, text: String) {
// Received text message
}
override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
// Received binary message
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
// Connection closing
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
// Connection failed
}
})
}
fun sendMessage(message: String) {
webSocket.send(message)
}
fun closeWebSocket() {
webSocket.close(1000, "Closing connection")
}
}3. Server-Sent Events (SSE)
Server-Sent Events allow the server to push data to the client over a single HTTP connection. It's a unidirectional communication method, suitable for scenarios where the server needs to send updates to the client.
Pros:
- Simple to implement
- Works over standard HTTP
- Automatic reconnection
Cons:
- Unidirectional (server to client only)
- Limited browser support (but can be used with libraries in Android)
Code Example:
import android.os.Handler
import android.os.Looper
import okhttp3.*
import java.io.IOException
class ServerSentEventsExample {
private lateinit var eventSource: EventSource
fun connectSSE() {
val client = OkHttpClient()
val request = Request.Builder()
.url("https://sse.example.com/events")
.build()
eventSource = EventSources.createFactory(client)
.newEventSource(request, object : EventSourceListener() {
override fun onOpen(eventSource: EventSource, response: Response) {
// Connection opened
}
override fun onEvent(
eventSource: EventSource,
id: String?,
type: String?,
data: String
) {
// Received event
Handler(Looper.getMainLooper()).post {
// Process event data on main thread
}
}
override fun onClosed(eventSource: EventSource) {
// Connection closed
}
override fun onFailure(eventSource: EventSource, t: Throwable?, response: Response?) {
// Error occurred
}
})
}
fun closeSSE() {
eventSource.cancel()
}
}Conclusion
Each of these methods has its strengths and use cases:
- HTTP Polling is simple but less efficient for frequent updates.
- WebSockets provide real-time, bidirectional communication, ideal for chat applications or live data streaming.
- Server-Sent Events offer a good balance between simplicity and efficiency for server-to-client updates.
When choosing a method for your Android app, consider factors such as update frequency, server capabilities, and the specific requirements of your application. By understanding these options, you can implement the most suitable real-time communication method for your project.