Sample Code for WebSocket Connector in Java
WebSockets provide a full-duplex communication channel over a single long-lived TCP connection. Thats meaning both parties can send and receive data simultaneously over the same connection, enabling real-time interaction between clients and servers. They are more efficient than traditional HTTP connections, which require constant re-establishment for data exchange.
The WebSocket protocol, standardized as RFC 6455, is distinct from HTTP but compatible with it. This compatibility allows Web Sockets to be used over the same ports as HTTP (80) and HTTPS (443), helping in easier integration with existing web infrastructures and overcoming firewall issues.
WebSockets start with an HTTP handshake, the connection starts with an HTTP request to upgrade the protocol to WebSocket. Once the handshake is successful, the connection remains open, then switch to the WebSocket protocol, maintaining a persistent connection. They support low-latency, bidirectional communication and can be secured using WSS, making them ideal for applications requiring instant updates, such as live chats, gaming, and financial tickers.
You can see the HTTP history for your WebSocket service, using some various of tools, as sample we can used Burp Suite
Prerequisites
This is the code
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.java_websocket.protocols.Protocol;
import javax.net.ssl.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
public class Main extends WebSocketClient {
private final Scanner scanner;
private final CountDownLatch connectionLatch;
private final LinkedBlockingQueue<String> responseQueue;
public Main(URI serverUri, Draft_6455 draft_ocppAndFallBack, CountDownLatch connectionLatch, LinkedBlockingQueue<String> responseQueue) {
super(serverUri, draft_ocppAndFallBack);
this.scanner = new Scanner(System.in);
this.connectionLatch = connectionLatch;
this.responseQueue = responseQueue;
}
public static void main(String[] args) throws URISyntaxException, InterruptedException, Exception {
URI serverUri = new URI("wss://<domain>:<port>/<path>");
Draft_6455 draft_ocppAndFallBack = createDraft();
CountDownLatch connectionLatch = new CountDownLatch(1);
LinkedBlockingQueue<String> responseQueue = new LinkedBlockingQueue<>();
// Create SSLContext that trusts all certificates
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
};
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an HostnameVerifier that bypasses hostname verification
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
Main c = new Main(serverUri, draft_ocppAndFallBack, connectionLatch, responseQueue);
c.setSocketFactory(sslContext.getSocketFactory());
c.connect();
}
private static Draft_6455 createDraft() {
Protocol trJson2Protocol = new Protocol("tr_json2");
return new Draft_6455(Collections.emptyList(), Collections.singletonList(trJson2Protocol));
}
public void connect() {
super.connect();
try {
connectionLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
sendUserInputMessages();
}
private void sendUserInputMessages() {
Thread thread = new Thread(() -> {
while (!Thread.interrupted()) {
System.out.println("- Type 'exit' to quit");
System.out.println("- Type 'check' to check connection");
System.out.println("- Type 'disconnect' to disconnect WebSocket");
System.out.print("Enter message to send: ");
String userInput = scanner.nextLine();
if ("exit".equalsIgnoreCase(userInput.trim())) {
System.out.println("Exiting...");
close();
break;
} else if ("check".equalsIgnoreCase(userInput.trim())) {
if (isOpen()) {
System.out.println("WebSocket connection is open.");
} else {
System.out.println("WebSocket connection is closed.");
}
} else if ("disconnect".equalsIgnoreCase(userInput.trim())) {
System.out.println("Disconnecting from WebSocket...");
close();
while (isOpen()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
System.out.println("Successfully disconnected from WebSocket.");
} else {
send(userInput);
try {
responseQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
System.out.println("WebSocket connection opened");
connectionLatch.countDown();
}
@Override
public void onMessage(String message) {
if (message.contains("{\"Type\":\"Ping\"}")) {
send("{\"Type\": \"Pong\"}");
return;
}
System.out.println("Message received from WebSocket server: " + message);
responseQueue.offer(message);
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("WebSocket connection closed: " + reason);
}
@Override
public void onError(Exception e) {
System.out.println("WebSocket error: ");
e.printStackTrace();
}
}
This is the Life Cycle
Happy Coding !