CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-http

HTTP client and server abstractions for Selenium WebDriver communication

Pending
Overview
Eval results
Files

websocket.mddocs/

WebSocket Support

WebSocket client functionality with message types (text, binary, close) and event-driven listener interface for real-time bidirectional communication.

Capabilities

WebSocket Interface

Main interface for WebSocket communication with message sending capabilities and resource management.

/**
 * WebSocket interface for bidirectional communication
 * Extends Closeable for proper resource management
 */
public interface WebSocket extends Closeable {
    /**
     * Logger instance for WebSocket operations
     */
    Logger LOG = Logger.getLogger(WebSocket.class.getName());
    
    /**
     * Sends a WebSocket message
     * @param message Message to send (TextMessage, BinaryMessage, or CloseMessage)
     * @return This WebSocket instance for chaining
     */
    WebSocket send(Message message);
    
    /**
     * Sends text message (convenience method)
     * @param data Text data to send
     * @return This WebSocket instance for chaining
     */
    default WebSocket sendText(CharSequence data);
    
    /**
     * Sends binary message (convenience method)
     * @param data Binary data to send
     * @return This WebSocket instance for chaining
     */
    default WebSocket sendBinary(byte[] data);
    
    /**
     * Closes the WebSocket connection
     */
    void close();
}

Usage Examples:

import org.openqa.selenium.remote.http.*;

// Open WebSocket connection via HTTP client
HttpRequest wsRequest = new HttpRequest(HttpMethod.GET, "/websocket");
wsRequest.addHeader("Upgrade", "websocket");

WebSocket.Listener listener = new WebSocket.Listener() {
    @Override
    public void onText(CharSequence data) {
        System.out.println("Received text: " + data);
    }
    
    @Override
    public void onBinary(byte[] data) {
        System.out.println("Received binary: " + data.length + " bytes");
    }
    
    @Override
    public void onClose(int code, String reason) {
        System.out.println("Connection closed: " + code + " - " + reason);
    }
    
    @Override
    public void onError(Throwable cause) {
        System.err.println("WebSocket error: " + cause.getMessage());
    }
};

WebSocket socket = client.openSocket(wsRequest, listener);

// Send different types of messages
socket.sendText("Hello WebSocket!");
socket.sendBinary("Binary data".getBytes());

// Send custom messages
socket.send(new TextMessage("Custom text message"));
socket.send(new BinaryMessage("Custom binary".getBytes()));

// Chaining method calls
socket.sendText("Message 1")
      .sendText("Message 2")
      .sendBinary("data".getBytes());

// Close connection
socket.close();

WebSocket Listener

Event-driven interface for handling incoming WebSocket messages and connection events.

/**
 * Listener interface for WebSocket events
 * Extends Consumer<Message> for functional interface compatibility
 */
public interface Listener extends Consumer<Message> {
    /**
     * Default message dispatcher that routes messages to specific handlers
     * @param message Incoming message (BinaryMessage, TextMessage, or CloseMessage)
     */
    default void accept(Message message);
    
    /**
     * Handles incoming binary messages
     * Default implementation does nothing
     * @param data Binary message data
     */
    default void onBinary(byte[] data);
    
    /**
     * Handles connection close events
     * Default implementation does nothing
     * @param code Close status code
     * @param reason Close reason string
     */
    default void onClose(int code, String reason);
    
    /**
     * Handles incoming text messages
     * Default implementation does nothing
     * @param data Text message data
     */
    default void onText(CharSequence data);
    
    /**
     * Handles WebSocket errors
     * Default implementation logs error at WARNING level
     * @param cause Error cause
     */
    default void onError(Throwable cause);
}

Usage Examples:

import org.openqa.selenium.remote.http.*;

// Full listener implementation
WebSocket.Listener fullListener = new WebSocket.Listener() {
    @Override
    public void onText(CharSequence data) {
        System.out.println("Text received: " + data);
        // Echo back
        if (socket != null) {
            socket.sendText("Echo: " + data);
        }
    }
    
    @Override
    public void onBinary(byte[] data) {
        System.out.println("Binary received: " + data.length + " bytes");
        // Process binary data
        processData(data);
    }
    
    @Override
    public void onClose(int code, String reason) {
        System.out.println("Connection closed with code " + code + ": " + reason);
        cleanup();
    }
    
    @Override
    public void onError(Throwable cause) {
        System.err.println("WebSocket error occurred: " + cause.getMessage());
        cause.printStackTrace();
        // Custom error handling
        handleError(cause);
    }
    
    private void processData(byte[] data) { /* process binary data */ }
    private void cleanup() { /* cleanup resources */ }
    private void handleError(Throwable cause) { /* handle error */ }
};

// Minimal listener (only text messages)
WebSocket.Listener textOnlyListener = new WebSocket.Listener() {
    @Override
    public void onText(CharSequence data) {
        System.out.println("Received: " + data);
    }
};

// Lambda-based listener using Consumer interface
WebSocket.Listener lambdaListener = message -> {
    if (message instanceof TextMessage) {
        System.out.println("Text: " + ((TextMessage) message).text());
    } else if (message instanceof BinaryMessage) {
        System.out.println("Binary: " + ((BinaryMessage) message).data().length + " bytes");
    }
};

// Use listeners with WebSocket
WebSocket socket1 = client.openSocket(wsRequest, fullListener);
WebSocket socket2 = client.openSocket(wsRequest, textOnlyListener);
WebSocket socket3 = client.openSocket(wsRequest, lambdaListener);

Message Types

Message Interface

Base interface for all WebSocket message types.

/**
 * Marker interface for WebSocket messages
 * Implemented by TextMessage, BinaryMessage, and CloseMessage
 */
public interface Message {
    // Marker interface - no methods
}

TextMessage

WebSocket text message implementation for string data.

/**
 * WebSocket text message containing string data
 */
public class TextMessage implements Message {
    /**
     * Creates text message from character sequence
     * @param text Text content for the message
     */
    public TextMessage(CharSequence text);
    
    /**
     * Gets the text content
     * @return Message text as String
     */
    public String text();
}

Usage Examples:

// Create and send text messages
TextMessage message1 = new TextMessage("Hello World");
TextMessage message2 = new TextMessage(new StringBuilder("Dynamic content"));

socket.send(message1);
socket.send(message2);

// Access text content
String content = message1.text();
System.out.println("Message content: " + content);

// Use in listener
WebSocket.Listener listener = new WebSocket.Listener() {
    @Override
    public void onText(CharSequence data) {
        // Can also receive via accept method:
    }
    
    @Override
    public void accept(Message message) {
        if (message instanceof TextMessage) {
            TextMessage textMsg = (TextMessage) message;
            System.out.println("Received text: " + textMsg.text());
        }
    }
};

BinaryMessage

WebSocket binary message implementation for byte data with defensive copying.

/**
 * WebSocket binary message containing byte data
 * Makes defensive copies to ensure data integrity
 */
public class BinaryMessage implements Message {
    /**
     * Creates binary message from ByteBuffer
     * Makes read-only copy of the buffer
     * @param data ByteBuffer containing binary data
     */
    public BinaryMessage(ByteBuffer data);
    
    /**
     * Creates binary message from byte array
     * Makes defensive copy of the array
     * @param data Byte array containing binary data
     */
    public BinaryMessage(byte[] data);
    
    /**
     * Gets the binary data
     * Returns copy of internal data to prevent modification
     * @return Byte array copy of message data
     */
    public byte[] data();
}

Usage Examples:

import java.nio.ByteBuffer;

// Create binary messages from byte array
byte[] imageData = loadImageData();
BinaryMessage imageMessage = new BinaryMessage(imageData);
socket.send(imageMessage);

// Create from ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Binary content".getBytes());
buffer.flip();
BinaryMessage bufferMessage = new BinaryMessage(buffer);
socket.send(bufferMessage);

// Access binary data (returns defensive copy)
byte[] messageData = imageMessage.data();
System.out.println("Message size: " + messageData.length + " bytes");

// Modify returned data doesn't affect original
byte[] data = imageMessage.data();
data[0] = 0; // This doesn't change the message's internal data

// Use in listener
WebSocket.Listener listener = new WebSocket.Listener() {
    @Override
    public void onBinary(byte[] data) {
        System.out.println("Received " + data.length + " bytes");
        processImageData(data);
    }
    
    @Override
    public void accept(Message message) {
        if (message instanceof BinaryMessage) {
            BinaryMessage binMsg = (BinaryMessage) message;
            byte[] data = binMsg.data();
            saveBinaryData(data);
        }
    }
    
    private void processImageData(byte[] data) { /* process image */ }
    private void saveBinaryData(byte[] data) { /* save to file */ }
};

CloseMessage

WebSocket close message with status code and reason.

/**
 * WebSocket close message with status code and optional reason
 */
public class CloseMessage implements Message {
    /**
     * Creates close message with status code only
     * @param code Close status code
     */
    public CloseMessage(int code);
    
    /**
     * Creates close message with status code and reason
     * @param code Close status code
     * @param reason Close reason string
     */
    public CloseMessage(int code, String reason);
    
    /**
     * Gets the close status code
     * @return Status code indicating close reason
     */
    public int code();
    
    /**
     * Gets the close reason string
     * @return Close reason or empty string if not provided
     */
    public String reason();
}

Usage Examples:

// Create close messages
CloseMessage normalClose = new CloseMessage(1000); // Normal closure
CloseMessage errorClose = new CloseMessage(1002, "Protocol error");
CloseMessage customClose = new CloseMessage(4000, "Custom application error");

// Send close messages
socket.send(normalClose);

// Access close information
int closeCode = errorClose.code();        // 1002
String closeReason = errorClose.reason(); // "Protocol error"

System.out.println("Closing with code " + closeCode + ": " + closeReason);

// Use in listener
WebSocket.Listener listener = new WebSocket.Listener() {
    @Override
    public void onClose(int code, String reason) {
        System.out.println("Connection closed: " + code + " - " + reason);
        
        // Handle different close codes
        switch (code) {
            case 1000:
                System.out.println("Normal closure");
                break;
            case 1001:
                System.out.println("Endpoint going away");
                break;
            case 1002:
                System.out.println("Protocol error");
                break;
            default:
                System.out.println("Other close reason: " + code);
        }
    }
    
    @Override
    public void accept(Message message) {
        if (message instanceof CloseMessage) {
            CloseMessage closeMsg = (CloseMessage) message;
            handleClose(closeMsg.code(), closeMsg.reason());
        }
    }
    
    private void handleClose(int code, String reason) {
        // Custom close handling logic
    }
};

WebSocket Connection Lifecycle

Complete example showing WebSocket connection lifecycle:

import org.openqa.selenium.remote.http.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class WebSocketExample {
    private WebSocket socket;
    private final CountDownLatch closeLatch = new CountDownLatch(1);
    
    public void connectAndCommunicate() throws InterruptedException {
        // Create HTTP client
        HttpClient client = HttpClient.Factory.createDefault()
            .createClient(new URL("wss://echo.websocket.org"));
        
        // Create WebSocket request
        HttpRequest wsRequest = new HttpRequest(HttpMethod.GET, "/");
        
        // Create listener
        WebSocket.Listener listener = new WebSocket.Listener() {
            @Override
            public void onText(CharSequence data) {
                System.out.println("Echo received: " + data);
            }
            
            @Override
            public void onClose(int code, String reason) {
                System.out.println("Connection closed: " + code + " - " + reason);
                closeLatch.countDown();
            }
            
            @Override
            public void onError(Throwable cause) {
                System.err.println("WebSocket error: " + cause.getMessage());
                closeLatch.countDown();
            }
        };
        
        // Open connection
        socket = client.openSocket(wsRequest, listener);
        
        // Send messages
        socket.sendText("Hello WebSocket!");
        socket.sendText("This is a test message");
        
        // Send binary data
        socket.sendBinary("Binary test data".getBytes());
        
        // Wait a bit for responses
        Thread.sleep(2000);
        
        // Close connection gracefully
        socket.send(new CloseMessage(1000, "Normal closure"));
        
        // Wait for close confirmation
        closeLatch.await(10, TimeUnit.SECONDS);
        
        // Cleanup
        client.close();
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-http

docs

client-config.md

content-handling.md

filtering.md

http-client.md

index.md

request-response.md

routing.md

websocket.md

tile.json