All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.xinyangpan.crypto4j.binance.websocket.impl.BinanceSubscriber Maven / Gradle / Ivy

There is a newer version: 0.1.4
Show newest version
package io.github.xinyangpan.crypto4j.binance.websocket.impl;

import static io.github.xinyangpan.crypto4j.core.util.Crypto4jUtils.objectMapper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;

import io.github.xinyangpan.crypto4j.binance.dto.depth.Depth;
import io.github.xinyangpan.crypto4j.binance.dto.websocket.Ticker;
import io.github.xinyangpan.crypto4j.binance.dto.websocket.common.StreamData;
import io.github.xinyangpan.crypto4j.binance.dto.websocket.userstream.AccountInfo;
import io.github.xinyangpan.crypto4j.binance.dto.websocket.userstream.ExecutionReport;
import io.github.xinyangpan.crypto4j.core.util.Crypto4jUtils;
import io.github.xinyangpan.crypto4j.core.websocket.Subscriber;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Getter
@Setter
public class BinanceSubscriber extends Subscriber {
	private final List streamNames = new ArrayList<>();
	private Consumer> depthListener = Crypto4jUtils.logConsumer();
	private Consumer> tickerListener = Crypto4jUtils.logConsumer();
	private Consumer accountInfoListener = Crypto4jUtils.logConsumer();
	private Consumer executionReportListener = Crypto4jUtils.logConsumer();

	@Override
	protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
		String jsonMessage = message.getPayload();
		log.debug(MSG_TRACK, "{}: handling message: {}", this.getName(), jsonMessage);
		JsonNode rootNode = objectMapper().readTree(jsonMessage);
		JsonNode eventTypeNode = rootNode.at("/e");
		if (!eventTypeNode.isMissingNode()) {
			userStream(jsonMessage, eventTypeNode);
			return;
		}
		JsonNode streamNode = rootNode.at("/stream");
		if (!streamNode.isMissingNode()) {
			marketStream(jsonMessage, streamNode);
			return;
		}
		this.unhandledMessage(jsonMessage);
	}

	private void userStream(String jsonMessage, JsonNode eventTypeNode) throws IOException, JsonParseException, JsonMappingException {
		String eventType = eventTypeNode.asText();
		switch (eventType) {
		case "outboundAccountInfo":
			accountInfoListener.accept(objectMapper().readValue(jsonMessage, AccountInfo.class));
			return;
		case "executionReport":
			executionReportListener.accept(objectMapper().readValue(jsonMessage, ExecutionReport.class));
			return;
		default:
			this.unhandledMessage(jsonMessage);
			return;
		}
	}

	private void marketStream(String jsonMessage, JsonNode streamNode) throws IOException, JsonParseException, JsonMappingException {
		String stream = streamNode.asText();
		DataType dataType = DataType.getDataType(stream);
		if (dataType == null) {
			this.unhandledMessage(jsonMessage);
			return;
		}
		JavaType javaType = dataType.getJavaType(objectMapper());
		switch (dataType) {
		case TICKER:
			tickerListener.accept(objectMapper().readValue(jsonMessage, javaType));
			return;
		case DEPTH:
			depthListener.accept(objectMapper().readValue(jsonMessage, javaType));
			return;
		default:
			this.unhandledMessage(jsonMessage);
			return;
		}
	}

	// -----------------------------
	// ----- Sub
	// -----------------------------

	public String getUrl(String websocketMarketBaseUrl) {
		return websocketMarketBaseUrl + this.getUrlParameter();
	}

	private String getUrlParameter() {
		return Joiner.on('/').join(streamNames);
	}

	public BinanceSubscriber depthAndTicker(int level, String... symbols) {
		Preconditions.checkNotNull(symbols);
		// 
		this.depth(level, symbols);
		this.ticker(symbols);
		return this;
	}

	public BinanceSubscriber depth(int level, String... symbols) {
		Preconditions.checkNotNull(symbols);
		// 
		for (String symbol : symbols) {
			streamNames.add(String.format("%s@depth%s", symbol, level));
		}
		return this;
	}

	public BinanceSubscriber ticker(String... symbols) {
		Preconditions.checkNotNull(symbols);
		// 
		for (String symbol : symbols) {
			streamNames.add(String.format("%s@ticker", symbol));
		}
		return this;
	}

	public BinanceSubscriber kline(String symbol, String interval) {
		streamNames.add(String.format("%s@kline_%s", symbol, interval));
		return this;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy