I am attempting to use the Java-Websocket library by TooTallNate to create a websocket client that receives messages from the coinbase exchange websocket stream . I am porting a program I made in Python to Java because of parallelisation bottlenecks in Python and to my knowledge I am doing things the same in Java as I did in Python. Here is my code to open the connection in Python using this websocket lib (This works as expected):
ws = websocket.create_connection("wss://ws-feed.exchange.coinbase.com", 20)
ws.send(json.dumps({
"type": "subscribe",
"product_id": "BTC-USD"
}))
Here is my entire Java class:
public class CoinbaseWebsocketClient extends WebSocketClient {
private final Gson gson = new Gson();
private CoinbaseWebsocketClient(URI serverURI) {
super(serverURI, new Draft_17());
connect();
}
private static URI uri;
private static CoinbaseWebsocketClient coinbaseWebsocketClient;
static {
try {
uri = new URI("wss://ws-feed.exchange.coinbase.com");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
protected static CoinbaseWebsocketClient get() {
if (coinbaseWebsocketClient == null) {
coinbaseWebsocketClient = new CoinbaseWebsocketClient(uri);
}
return coinbaseWebsocketClient;
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
System.out.println("Websocket open");
final JsonObject btcUSD_Request = new JsonObject();
btcUSD_Request.addProperty("type", "subscribe");
btcUSD_Request.addProperty("product_id", "BTC_USD");
final String requestString = gson.toJson(btcUSD_Request);
send(requestString);
}
@Override
public void onMessage(String s) {
System.out.println("Message received: " + s);
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("Websocket closed: " + reason);
}
@Override
public void onError(Exception e) {
System.err.println("an error occurred:" + e);
}
}
I know there isn't a totally fundamental issue with my Java code because it works as expected when I use ws://echo.websocket.org as the URI instead of wss://ws-feed.exchange.coinbase.com. However when I try to connect to wss://ws-feed.exchange.coinbase.com I get this error:
Websocket closed: draft org.java_websocket.drafts.Draft_17@7ca2fefb refuses handshake
There is no authentication or anything like for this connection as far as I know (I didn't provide any in my Python program) so I'm at a loss as to what the source of this error is.
Need to create sslcontext like below. it skips the certificate. I was successfully able make a connection without certificate
SSLContext sslContext = SSLContext.getInstance("SSL");
// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
System.out.println("getAcceptedIssuers =============");
return null;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkClientTrusted =============");
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) {
System.out.println("checkServerTrusted =============");
}
} }, new SecureRandom());
You need to call the setSocket()
method before doing the connect()
, eg:
private CoinbaseWebsocketClient(URI serverURI) {
super(serverURI, new Draft_17());
setSocket(SSLSocketFactory.getDefault().createSocket(serverURI.getHost(), serverURI.getPort()));
connect();
}
Good luck!
A note: Beware that your singleton get()
might not be a good idea in case of any failures (if I remember correctly the client class is unusable after unrecoverable error and you have to create a new client to recover).
vlp is almost right. But should hard code 443 as port parameter:
private CoinbaseWebsocketClient(URI serverURI) {
super(serverURI, new Draft_17());
setSocket(SSLSocketFactory.getDefault().createSocket(serverURI.getHost(), 443));
connect();
}
That works for me!
PS. the ssl must be a valid certificate one, otherwise you can not just use getDefault method to get ssl context. For self-singed, etc. please refer to following link:
http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.