diff --git a/ParseLiveQuery/build.gradle b/ParseLiveQuery/build.gradle index cd92498..d03aadb 100644 --- a/ParseLiveQuery/build.gradle +++ b/ParseLiveQuery/build.gradle @@ -42,6 +42,7 @@ android { dependencies { compile 'com.parse:parse-android:1.13.1' compile 'com.firebase:tubesock:0.0.12' + compile 'com.squareup.okhttp3:okhttp:3.6.0' compile 'com.parse.bolts:bolts-tasks:1.4.0' testCompile 'org.robolectric:robolectric:3.0' diff --git a/ParseLiveQuery/src/main/java/com/parse/OkHttp3WebSocketClient.java b/ParseLiveQuery/src/main/java/com/parse/OkHttp3WebSocketClient.java new file mode 100644 index 0000000..545a8de --- /dev/null +++ b/ParseLiveQuery/src/main/java/com/parse/OkHttp3WebSocketClient.java @@ -0,0 +1,110 @@ +package com.parse; + +import android.util.Log; + +import java.net.URI; +import java.util.Locale; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + +/* package */ class OkHttp3WebSocketClient implements WebSocketClient { + + private static final String LOG_TAG = "OkHttpWebSocketClient"; + + private final WebSocketClientCallback webSocketClientCallback; + private WebSocket webSocket; + private State state = State.NONE; + private final OkHttpClient client; + private final String url; + private final int STATUS_CODE = 200; + private final String CLOSING_MSG = "User invoked close"; + + private final WebSocketListener handler = new WebSocketListener() { + @Override + public void onOpen(WebSocket webSocket, Response response) { + setState(State.CONNECTED); + webSocketClientCallback.onOpen(); + } + + @Override + public void onMessage(WebSocket webSocket, String text) { + webSocketClientCallback.onMessage(text); + } + + @Override + public void onMessage(WebSocket webSocket, ByteString bytes) { + Log.w(LOG_TAG, String.format(Locale.US, "Socket got into inconsistent state and received %s instead.", bytes.toString())); + } + + @Override + public void onClosed(WebSocket webSocket, int code, String reason) { + setState(State.DISCONNECTED); + webSocketClientCallback.onClose(); + } + + @Override + public void onFailure(okhttp3.WebSocket webSocket, Throwable t, Response response) { + webSocketClientCallback.onError(t); + } + }; + + private OkHttp3WebSocketClient(OkHttpClient okHttpClient, WebSocketClientCallback webSocketClientCallback, URI hostUrl) { + client = okHttpClient; + this.webSocketClientCallback = webSocketClientCallback; + url = hostUrl.toString(); + } + + @Override + public synchronized void open() { + if (State.NONE == state) { + // OkHttp3 connects as soon as the socket is created so do it here. + Request request = new Request.Builder() + .url(url) + .build(); + + webSocket = client.newWebSocket(request, handler); + setState(State.CONNECTING); + } + } + + @Override + public synchronized void close() { + setState(State.DISCONNECTING); + webSocket.close(STATUS_CODE, CLOSING_MSG); + } + + @Override + public void send(String message) { + if (state == State.CONNECTED) { + webSocket.send(message); + } + } + + @Override + public State getState() { + return state; + } + + private synchronized void setState(State newState) { + this.state = newState; + this.webSocketClientCallback.stateChanged(); + } + + /* package */ static class OkHttp3SocketClientFactory implements WebSocketClientFactory { + @Override + public WebSocketClient createInstance(WebSocketClientCallback webSocketClientCallback, URI hostUrl) { + return new OkHttp3WebSocketClient(new OkHttpClient(), webSocketClientCallback, hostUrl); + } + + public WebSocketClient createInstance(OkHttpClient client, WebSocketClientCallback webSocketClientCallback, URI hostUrl) { + return new OkHttp3WebSocketClient(client, webSocketClientCallback, hostUrl); + } + + } + +} diff --git a/ParseLiveQuery/src/main/java/com/parse/ParseLiveQueryClientImpl.java b/ParseLiveQuery/src/main/java/com/parse/ParseLiveQueryClientImpl.java index a4873b6..96d83cb 100644 --- a/ParseLiveQuery/src/main/java/com/parse/ParseLiveQueryClientImpl.java +++ b/ParseLiveQuery/src/main/java/com/parse/ParseLiveQueryClientImpl.java @@ -292,7 +292,7 @@ public void onClose() { } @Override - public void onError(Exception exception) { + public void onError(Throwable exception) { Log.e(LOG_TAG, "Socket onError", exception); } diff --git a/ParseLiveQuery/src/main/java/com/parse/WebSocketClient.java b/ParseLiveQuery/src/main/java/com/parse/WebSocketClient.java index 5c288c6..2c7fb0a 100644 --- a/ParseLiveQuery/src/main/java/com/parse/WebSocketClient.java +++ b/ParseLiveQuery/src/main/java/com/parse/WebSocketClient.java @@ -17,7 +17,7 @@ interface WebSocketClientCallback { void onClose(); - void onError(Exception exception); + void onError(Throwable exception); void stateChanged(); }