WebSocket is an application
protocol that provides full-duplex communications between two peers over the
TCP protocol.
In a WebSocket application,
the server publishes a WebSocket endpoint, and the client uses the endpoint's
URI to connect to the server. The WebSocket protocol is symmetrical after the
connection has been established; the client and the server can send messages to
each other at any time while the connection is open, and they can close the
connection at any time. Clients usually connect only to one server, and servers
accept connections from multiple clients.
The WebSocket protocol has
two parts: handshake and data transfer. The client initiates the handshake by
sending a request to a WebSocket endpoint using its URI. The handshake is
compatible with existing HTTP-based infrastructure: web servers interpret it as
an HTTP connection upgrade request.
The server applies a known
operation to the value of the Sec-WebSocket-Key header to generate the value of
the Sec-WebSocket-Accept header. The client applies the same operation to the
value of the Sec-WebSocket-Key header, and the connection is established
successfully if the result matches the value received from the server. The
client and the server can send messages to each other after a successful
handshake.
WebSocket endpoints are
represented by URIs that have the following form:
ws://host:port/path?query
wss://host:port/path?query
The ws scheme represents an
unencrypted WebSocket connection, and the wss scheme represents an encrypted
connection. The port component is optional; the default port number is 80 for
unencrypted connections and 443 for encrypted connections. The path component
indicates the location of an endpoint within a server. The query component is
optional.
Example : -
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
public class WebSocketClientHandler extends TextWebSocketHandler{
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Inside client
afterConnectionEstablished :: sessionId :: " + session.getId());
session.sendMessage(new TextMessage("Sending message to
server..."));
}
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message)
throws Exception {
System.out.println("Client Recieved Message :: "+message.toString());
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("Exception occured :: " + session.getId());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("Client connection closed for sessionId :: " + session.getId());
}
@Override
public boolean supportsPartialMessages() {
return true;
}
Server Handler
:
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.google.gson.Gson;
@Component
public class WebSocketServerHandler extends TextWebSocketHandler {
private static Logger logger = LoggerFactory.getLogger(WebSocketServerHandler.class);
List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
logger.info("Inside server
afterConnectionEstablished:: sessionId:: " + session.getId());
}
@SuppressWarnings("rawtypes")
@Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String echoMessage = message.getPayload();
logger.info(echoMessage);
for(WebSocketSession webSocketSession : sessions) {
Map value = new Gson().fromJson(message.getPayload(), Map.class);
webSocketSession.sendMessage(new TextMessage("Hello " + value.get("name") + " !"));
}
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
session.close(CloseStatus.SERVER_ERROR);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("Inside Server afterConnectionClosed for sessionId ::
" + session.getId());
}
}