We are building a chat application in Android. We are thinking of using HTTP REST API to send outbound messages. Wanted to know if its a good approach or has any downsides compared to using WebSockets or XMPP (which seems to be more of a defacto standard for transferring chat messages) ?
Some of the pros/cons I can think are:
+ HTTP endpoint is easy to scale horizontally on server side (This is a main concern)
+ Learning curve for Websockets is steeper compared to HTTP
– HTTP messages would have larger payload compared to websockets
As per this document, it seems even Facebook used AJAX to handle chat messages initially:
We can use REST API for chat messaging, but IMHO, XMPP is a better alternative. Let’s consider what XMPP has to offer.
XMPP beside supporting TCP transport also provides HTTP (via polling and binding) and websocket transports. Read XMPP via HTTP and WebSocket transports
It would be interesting to understand pros and cons of each transport from XMPP perspective.
XMPP could use HTTP in two ways: polling and binding.
XMPP over HTTP Polling
method, now deprecated, essentially implies messages stored on a
server-side database are being fetched (and posted) regularly by an
XMPP client by way of HTTP ‘GET’ and ‘POST’ requests.
XMPP over HTTP Binding (BOSH)
The binding method is considered more efficient than the regular HTTP ‘GET’ and ‘POST’ requests in Polling method because it reduces latency and bandwidth consumption over other HTTP polling techniques
However, this also poses a disadvantage that sockets remain open for an extended length of time, awaiting the client’s next request
The binding method, implemented using Bidirectional-streams Over Synchronous HTTP
(BOSH), allows servers to push messages to clients as soon as they
are sent. This push model of notification is more efficient than
polling, where many of the polls return no new data.
It would be good if we understand how the BOSH technique works.
The technique employed by BOSH, which is sometimes called “HTTP long
polling”, reduces latency and bandwidth consumption over other HTTP
polling techniques. When the client sends a request, the connection
manager does not immediately send a response; instead it holds the
request open until it has data to actually send to the client (or an
agreed-to length of inactivity has elapsed). The client then
immediately sends a new request to the connection manager, continuing
the long polling loop.
If the connection manager does not have any data to send to the client
after some agreed-to length of time , it sends a response with an
empty . This serves a similar purpose to whitespace keep-alives
or XMPP Ping (XEP-0199) ; it helps keep a socket connection active
which prevents some intermediaries (firewalls, proxies, etc) from
silently dropping it, and helps to detect breaks in a reasonable
amount of time.
XMPP over WebSocket binding
XMPP supports WebSocket binding which is a more efficient transport
A perhaps more efficient transport for real-time messaging is
WebSocket, a web technology providing for bi-directional, full-duplex
communications channels over a single TCP connection. XMPP over
WebSocket binding is defined in the IETF proposed standard RFC 7395.
Speaking of the learning curve, yes, you might be tempted to use the REST API, but now there are several resources to learn about Android and XMPP, and XMPP server softwares that you can use to run your own XMPP service, either over the Internet or on a local area network. It would be worth spending this effort before you decide your architecture.
I think a REST approach can work for chat. Let’s assume:
- http://chat.example.com/conversations references all conversations
- GET fetches the list
- POST creates a new one
- http://chat.example.com/conversations/123 references conversation #123
- GET fetches messages in this conversation
- POST adds a message in the conversation
If I understand correctly, your question is about the last point.
Once the client has posted an outboud message to http://chat.example.com/conversations/123, it will close the http connection.
The drawback is that receiving inbound messages is simply not possible in that case. You will need a different channel (maybe simply Google cloud messaging).
On the contrary, WebSockets and XMPP keep the connection alive, hence they can receive messages with no delay. But the drawback of both of them is indeed that this represents a cost on the server, in terms of scalability ; and a cost on the client in terms of battery usage.
On the server:
- sockets are a relative scarce resource
- it’s not possible to move clients for load balancing if they have an open connection (but can you really move clients anyway? this depends on the responsibility of tiers)
On the client:
- maintaining a network connection is extremely expensive. 1 s network ≈ 5 min sleep.
- the XMPP librairies are not necessarily working very well on Android.
And I’ve no idea of support of WebSockets on android.
It is not suggested to use HTTP Rest API for chat or similar realtime applications.
Chat Client requirements
Friend list fetch
Check online / offline friends
- Get chat messages in realtime and send messages .
- Receive notifications of delivery/reading etc.
Point 1 is sort of one time job after you start chat client so can be done with simple rest call so no complicated overhead.
Rest all points will need persistent checking of data from server or other part in case of p2p client also. Which will make you to create either long or short polling rest calls to watch for new data or another updates.
Problem with HTTP Rest client
It is not a keep alive type communication due to which you will have to make multiple http connections which will have so much overhead that it will become overly laggy. As reconnecting is very costly in HTTP calls.
**Web sockets or XMPP **
They are duplex mode of communication and are very good at handling incremental data pushes and you are not creating new http connections again so it gives real smooth performance.
In case you are stuck with some legacy systems in case of which you are bound to use the rest api mode.
Try CometD it is a hybrid approach of websockets and ajax polling which will give you near realtime communications as well as working on clients which does not support websockets by falling back on ajax polling mechanisms. Also it uses various optimizations to avoid reconnecting again and again.
You can also try Socket.io which is also an amazing technology to solve these kind of use cases
Short answer No.
I would not start a new project or recommend starting a new project (since you mentioned start afresh) that needs a live bi-directional communication that relies on HTTP – as stateless protocol. You may take comfort that the connection is kept alive but there is no guarantee.
+ HTTP endpoint is easy to scale horizontally on server side pro is a pro in the context when HTTP is used as request and response style and when it is considered stateless. It becomes somewhat moot (although not entirely) when you inherently need to keep the connection alive.
HTTP does offer another following benefit that you have not mentioned in here.
- HTTP is easy to deal with corporate firewall proxies when other ports may be blocked.
This is where WebSockets or XMPP over HTTP will have better success rate as mentioned by others.
It depends. Do you consider your application to be “live chat”? Do you require a presence indicator, or typing indicator? Features such as those require continuous connection. But there’s another set of chat applications that you’d describe as “in-app messaging” enabled. These applications store conversations and conversation lists on some sort of backend; just install the app on another device and log in, and you’ll see your conversations on this type of app. These apps don’t have any presence indicator, or feeling of liveness.
Although I haven’t implemented any applications with XMPP, it looks like as far as message persistence, the most persistence you’ll find with XMPP (out of the box) is persist-until-delivered, similar to SMS. Perhaps you could build a storage/recovery mechanism for XMPP by capturing stanzas as they pass through and storing them in your own DB. But if you don’t need the full “chat” experience, using a database, HTTP service and push notifications (to notify of updated threads) seems like a solid path for apps with messaging functionality — which I intend to implement in an iOS & Android app of my own right now.
Let me know if you’ve found any good open-source schemas/API design for this.