Saturday, May 16, 2015

Websocket in Java

Covered the fundamentals of web sockets (vs HTTP) in the previous post, here

WebSocket protocol is part of HTML5 specification to provide full-duplex bi-directional communication channel over single TCP socket. It got added in Java EE version 7 (JRS 356). In this post, I will dig dipper into WebSockets and how can we implement it in Java. 


WebSocket uses HTTP connection to bootstrap itself. HTTP sends a normal request to initiate WebSocket connection but it has upgrade header (wiki link). Through this upgrade header, clients say that it would like to upgrade current HTTP connection to a different protocol connection.  If sever has support for it websocket connection gets established. Once the connection is established, both ends can transfer data.


Life Cycle of WebSockets

  1. The client sends an HTTP request to the server with an upgrade header having value websocket.
  2. If Server supports WebSockets then it responds with HTTP header having status code 101, which means now onwards the connection is upgraded to WebSockets (no more HTTP).
  3. Now both client and server can send any number of messages to each other.  Server needs to obtain the session object to send message to client. 
Image Source

Client Request
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

Server Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

Implementation

Specification JRS 356, covers standards for Java client side as well as server-side WebSocket implementation. This is part of Java EE 7, so all Java EE 7 compliant application servers should provide WebSockets support. There are also independent libraries/jars which can be used to support this feature on non EE 7 compliant servers. 

Any POJO class can be turned into a WebSocket server endpoint by annotating it properly. As shown in below diagram, the class needs to be annotated with @ServerEndPoint and specify URL as the value. You just need to provide implementations of the callback methods which will be called appropriately during the lifespan of the connection. Your server will ensure that these methods get invoked appropriately.




Just like a server endpoint, client endpoint can also be created in Java by annotating the class with @ClientEndPoint and by providing implementations of lifecycle methods. WebSocket client endpoint initiates the connection and WebSocket server endpoints await for the request and establish it. Once the connection is established the request data will be received in the onMessage callback method. So this is the place where business logic will be put. Both client and server can keep sending the data to the other party unless the connection is closed.

Over the internet, clients will mostly be a browser, so make sure that your browser supports this. Both endpoints (client and server) have callback listeners- onOpen, onMessage, onError, onClose.

Please refer to this link which describes steps to create WebSocket in Java.

I have also hosted a hello world WebSocket application on GitHub (websockets).

Security

This is a new technology and hence concern for security is legitimate. Here is a nice article which covers some of the important aspects. 

Final Note

  1. WebSocket protocol is supported in major browsers- Chrome, IE, Firefox, Safari. It also requires support from the server web app. Check for its support on your Android/iOS version if you want to use it for the mobile client. 
  2. It opens connections on TCP port 80. 
  3. WebSockets transmissions are described as messages, where a single message can be optionally split across several data frames. 
  4. Good to validate Origin header before establishing connection on server side to avoid any security threat. 
  5. WebSocket protocol defines a ws:// and wss:// prefix to indicate a WebSocket and a secure WebSocket connection, respectively. 
  6. WebSocket is stateful (unlike http which is stateless), so it doesn't scale up nicely. 
  7. One of the issue with WebSockets is that, what if proxy times out connection after some inactivity? Client and server should re-handshake to ensure that connections gets established again. 
  8. Another legitimate question is, what if either of proxy or browser doesn't support it. You can use portable frameworks like Atmosphere. It transparently falls back to HTTP in such case. 

References:

---
keep coding !

No comments:

Post a Comment