В настоящее время я экспериментирую с Binance Websocket (https://binance-docs.github.io/apidocs/spot/en/#websocket-market-streams), передавая данные свечей для обработки.
Как задокументировано, поток будет случайным образом закрыт через 24 часа. Как лучше всего продолжить сеанс без перерыва? Я имею в виду отключение/повторное подключение через 23 часа, чтобы программа продолжила работу без потери своего состояния.
Вот что я сделал. Я использую binance-java-api https://github.com/binance-exchange/binance-java-api.
И вот как я подключаюсь:
BinanceApiWebSocketClient client =
BinanceApiClientFactory.newInstance(
appConfig.getApiKey(),
appConfig.getApiSecret(),
appConfig.isUseTestNet(),
appConfig.isUseTestNet())
.newWebSocketClient();
client.onCandlestickEvent(cryptoPair.toLowerCase(), getCandlestickInterval(),
new BinanceApiCallback<>() {
@Override
public void onResponse(final CandlestickEvent evt) {}
«Лучший» способ — это тот, который вы попробуете последним.
Чтобы решить эту проблему, я использовал планировщик/таймер для повторного подключения сеанса каждые 12 часов. Поскольку я использую фреймворк Quarkus, он легко доступен.
Решение: Класс SessionManager:
@Singleton
@Slf4j
@RequiredArgsConstructor
public class SessionManagerScheduler {
final BinanceEventHandler binanceEventHandler;
@Scheduled(cron = "0 2 */12 * * ?")
public void reconnectSession() {
log.info("Keep-Alive: Binance Session Via WebSocket -------------------------");
binanceEventHandler.timeout();
}
}
Обработчик события Binance:
@ApplicationScoped
@Slf4j
@RequiredArgsConstructor
public class BinanceEventHandler {
final AppConfig appConfig;
final CandlestickAccumulator candlestickAccumulator;
final CandlestickMapper candlestickMapper;
private Closeable candleStream = null;
public void start() {
streamCandleEvent();
}
public void timeout() {
try {
candleStream.close();
streamCandleEvent();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void streamCandleEvent() {
String cryptoPair = String.join(",", appConfig.getCryptoPairs());
log.info("Start listening to cryptoPair = {}", cryptoPair);
candleStream = getClient().onCandlestickEvent(cryptoPair.toLowerCase(), getCandlestickInterval(),
new BinanceApiCallback<>() {
@Override
public void onResponse(final CandlestickEvent evt) {
if (!evt.getBarFinal()) {
return;
}
log.debug("Processing cryptoPair = {}, event = {}", cryptoPair, evt);
Candlestick candlestick = candlestickMapper.asCandleStick(evt);
candlestickAccumulator.processCandlestickEvent(candlestick);
}
@Override
public void onFailure(final Throwable cause) {
Application.hasError = true;
log.error("Fail connecting to Binance API {}", cause.getMessage());
}
}
);
}
private BinanceApiWebSocketClient getClient() {
return BinanceApiClientFactory.newInstance(
appConfig.getApiKey(),
appConfig.getApiSecret(),
appConfig.isUseTestNet(),
appConfig.isUseTestNet())
.newWebSocketClient();
}
private CandlestickInterval getCandlestickInterval() {
return CandlestickInterval.valueOf(appConfig.getCandlestickInterval());
}
}
Вы не указываете, как вы подключаетесь к веб-сокету, поэтому вам вряд ли удастся помочь. Кроме того, вы должны объяснить, в чем именно заключается проблема с автоматическим повторным подключением.