Why this code does not receive any message:
public class MainClass {
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(1);
try (HttpClient client = HttpClient.newHttpClient()) {
client.newWebSocketBuilder()
.buildAsync(URI.create("wss://socket.coinex.com/v2/futures"), new WebSocketClient(latch))
.join();
latch.wait();
}
}
private record WebSocketClient(CountDownLatch latch) implements WebSocket.Listener {
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("Connected to server");
String message = """
{
"method": "state.subscribe",
"params": {"market_list": ["BTCUSDT"]},
"id": 1
}
""";
webSocket.sendText(message, true);
WebSocket.Listener.super.onOpen(webSocket);
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
System.out.println("Receive: " + data.toString());
latch.countDown();
return WebSocket.Listener.super.onText(webSocket, data, last);
}
@Override
public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
System.out.println("Socket Closed: " + statusCode);
latch.countDown();
return WebSocket.Listener.super.onClose(webSocket, statusCode, reason);
}
@Override
public void onError(WebSocket webSocket, Throwable error) {
System.out.println("Error: " + error.getMessage());
latch.countDown();
WebSocket.Listener.super.onError(webSocket, error);
}
}
}
I check connection with this command :
websocat --uncompress-gzip --binary wss://socket.coinex.com/v2/futures
# After connect enter this message to receive response :
{"method": "state.subscribe","params": {"market_list": ["BTCUSDT"]},"id": 1}
I know messages should be decompressed on onText()
method .
but my problem is this method not receive any data from server !
As indicated by your websocat
command, the API is sending binary messages, not text messages. So, you should be overriding onBinary
to process the messages instead of onText
. Also as indicated by your websocat
command, you'll have to decompress the data. Your listener might look something like:
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.http.WebSocket;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import java.util.zip.GZIPInputStream;
public class FuturesListener implements WebSocket.Listener {
private final Consumer<String> onMessage;
public FuturesListener(Consumer<String> onMessage) {
this.onMessage = onMessage;
}
@Override
public void onOpen(WebSocket webSocket) {
System.out.println("onOpen");
webSocket.sendText(
"""
{
"method": "state.subscribe",
"params": {"market_list": ["BTCUSDT"]},
"id": 1
}
""",
true);
webSocket.request(1);
}
@Override
public CompletionStage<?> onBinary(WebSocket webSocket, ByteBuffer data, boolean last) {
onMessage.accept(new String(decompress(data), StandardCharsets.UTF_8));
webSocket.request(1);
return null;
}
private byte[] decompress(ByteBuffer data) {
byte[] buf = new byte[data.remaining()];
data.get(buf);
try {
var stream = new GZIPInputStream(new ByteArrayInputStream(buf));
return stream.readAllBytes();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}
Note the above omits any onError
and onClose
handling.