Skip to content

Instantly share code, notes, and snippets.

@mesudip
Last active June 14, 2024 05:31
Show Gist options
  • Save mesudip/94d49905375cba57950d69c119c97d4b to your computer and use it in GitHub Desktop.
Save mesudip/94d49905375cba57950d69c119c97d4b to your computer and use it in GitHub Desktop.
A client that reconnects
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.framing.Framedata;
import org.web3j.protocol.websocket.WebSocketClient;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.NotYetConnectedException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
@Slf4j
public class CustomWebSocketClient extends WebSocketClient {
public interface ReconnectHandlerInterface{
void onReconnect();
}
ArrayList<ReconnectHandlerInterface> handlers=new ArrayList<>();
@Synchronized
private void doReconnect(){
if(this.isClosed()){
try {
this.reconnectBlocking();
for (ReconnectHandlerInterface handler : handlers) {
handler.onReconnect();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Current thread needs to shutdown, Reconnect to websocket failed");
}
}
}
public void addReconnectHandler(ReconnectHandlerInterface handler){
handlers.add(handler);
}
public void removeReconnectHandler(ReconnectHandlerInterface handler){
handlers.remove(handler);
}
public CustomWebSocketClient(URI serverUri) {
super(serverUri);
}
public CustomWebSocketClient(URI serverUri, Map<String, String> httpHeaders) {
super(serverUri, httpHeaders);
}
@Override
public void send(String text) throws NotYetConnectedException {
doReconnect();
super.send(text);
}
@Override
public void send(byte[] data) throws NotYetConnectedException {
doReconnect();
super.send(data);
}
@Override
public void sendPing() throws NotYetConnectedException {
doReconnect();
super.sendPing();
}
@Override
@Synchronized
public void onClose(int code, String reason, boolean remote) {
if(remote || code!=1000){
this.doReconnect();
log.info("Reconnecting WebSocket connection to {}, because of disconnection reason: '{}'.",uri, reason);
}else {
super.onClose(code, reason, remote);
}
}
@Override
public void sendFragmentedFrame(Framedata.Opcode op, ByteBuffer buffer, boolean fin) {
doReconnect();
super.sendFragmentedFrame(op, buffer, fin);
}
@Override
public void send(ByteBuffer bytes) throws IllegalArgumentException, NotYetConnectedException {
doReconnect();
super.send(bytes);
}
@Override
public void sendFrame(Framedata framedata) {
doReconnect();
super.sendFrame(framedata);
}
@Override
public void sendFrame(Collection<Framedata> frames) {
doReconnect();
super.sendFrame(frames);
}
}
@thmarx
Copy link

thmarx commented Oct 8, 2021

you made my day

@peterdeenichin
Copy link

peterdeenichin commented Nov 5, 2022

Hello, I am very new to Java and struggling to understand how to implement this workaround to be able to reconnect.

I am interested in receiving the time stamp of when a new block has been created, which I currently achieve in the following way:

`public class WebSocketTestDiscordQuestion {

//Here I paste my websocket address
static final String INFURA_WS = "wss://my infura websocket address";

public static void main(String[] args) throws URISyntaxException, ConnectException {

    URI uri = new URI(INFURA_WS);
    CustomWebSocketClient webSocketClient = new CustomWebSocketClient(uri);
    WebSocketService web3jService = new WebSocketService(webSocketClient, true);
    web3jService.connect();
    Web3j web3j = Web3j.build(web3jService);

    web3j.blockFlowable(false)
            .subscribe(ethBlock -> {
                        EthBlock.Block block = ethBlock.getBlock();
                        LocalDateTime timestampNode = Instant.ofEpochSecond(
                                        block.getTimestamp()
                                                .longValueExact())
                                .atZone(ZoneId.of("UTC"))
                                .toLocalDateTime();


                        System.out.println(block.getNumber());
                        System.out.println(timestampNode);
                    }
                    , e -> {
                        System.out.println("It broke.");
                    }
            );
}

}
`

Eventually it breaks, but I want to keep it open indefinately. Can you please help me with an example of how to implement?

@yanshihong-hub
Copy link

you made my day

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment