Commit 75bf293c authored by Leonardo Aramaki's avatar Leonardo Aramaki

Upon failure, do unregister of current listeners and register them

all again with the new dppclient just reconnected
parent a604ae0d
...@@ -24,13 +24,10 @@ public class DDPClientImpl { ...@@ -24,13 +24,10 @@ public class DDPClientImpl {
private final DDPClient client; private final DDPClient client;
private RxWebSocket websocket; private RxWebSocket websocket;
private Flowable<RxWebSocketCallback.Base> flowable; private Flowable<RxWebSocketCallback.Base> flowable;
private CompositeDisposable subscriptions; private CompositeDisposable disposables;
private OkHttpClient okHttpClient;
private String currentSession; private String currentSession;
private String url;
public DDPClientImpl(DDPClient self, OkHttpClient client) { public DDPClientImpl(DDPClient self, OkHttpClient client) {
okHttpClient = client;
websocket = new RxWebSocket(client); websocket = new RxWebSocket(client);
this.client = self; this.client = self;
} }
...@@ -57,28 +54,24 @@ public class DDPClientImpl { ...@@ -57,28 +54,24 @@ public class DDPClientImpl {
public void connect(final TaskCompletionSource<DDPClientCallback.Connect> task, final String url, public void connect(final TaskCompletionSource<DDPClientCallback.Connect> task, final String url,
String session) { String session) {
try { try {
this.url = url;
flowable = websocket.connect(url).autoConnect(); flowable = websocket.connect(url).autoConnect();
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.retry().filter(callback -> callback instanceof RxWebSocketCallback.Open) flowable.retry().filter(callback -> callback instanceof RxWebSocketCallback.Open)
.subscribe( .subscribe(
callback -> { callback ->
sendMessage("connect", sendMessage("connect",
json -> (TextUtils.isEmpty(session) ? json : json.put("session", DDPClientImpl.this.currentSession)) json -> (TextUtils.isEmpty(session) ? json : json.put("session", DDPClientImpl.this.currentSession))
.put( .put(
"version", "pre2") "version", "pre2")
.put("support", new JSONArray().put("pre2").put("pre1")), .put("support", new JSONArray().put("pre2").put("pre1")),
task); task),
}, RCLog::e
err -> {
System.err.println("Something bad happened!");
}
) )
); );
subscriptions.add( disposables.add(
flowable.filter( flowable.filter(
callback -> callback instanceof RxWebSocketCallback.Message) callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
...@@ -90,22 +83,22 @@ public class DDPClientImpl { ...@@ -90,22 +83,22 @@ public class DDPClientImpl {
currentSession = response.optString("session"); currentSession = response.optString("session");
task.trySetResult( task.trySetResult(
new DDPClientCallback.Connect(client, response.optString("session"))); new DDPClientCallback.Connect(client, response.optString("session")));
subscriptions.dispose(); disposables.clear();
} else if ("error".equals(msg) && "Already connected".equals( } else if ("error".equals(msg) && "Already connected".equals(
response.optString("reason"))) { response.optString("reason"))) {
task.trySetResult(new DDPClientCallback.Connect(client, null)); task.trySetResult(new DDPClientCallback.Connect(client, null));
subscriptions.dispose(); disposables.clear();
} else if ("failed".equals(msg)) { } else if ("failed".equals(msg)) {
task.trySetError( task.trySetError(
new DDPClientCallback.Connect.Failed(client, response.optString("version"))); new DDPClientCallback.Connect.Failed(client, response.optString("version")));
subscriptions.dispose(); disposables.clear();
} }
}, },
err -> task.trySetError(new DDPClientCallback.Connect.Timeout(client)) err -> task.trySetError(new DDPClientCallback.Connect.Timeout(client))
) )
); );
addErrorCallback(subscriptions, task); addErrorCallback(disposables, task);
subscribeBaseListeners(); subscribeBaseListeners();
} catch (Exception e) { } catch (Exception e) {
...@@ -121,9 +114,9 @@ public class DDPClientImpl { ...@@ -121,9 +114,9 @@ public class DDPClientImpl {
sendMessage("ping", json -> json.put("id", id)); sendMessage("ping", json -> json.put("id", id));
if (requested) { if (requested) {
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message) flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson) .map(DDPClientImpl::toJson)
...@@ -134,12 +127,12 @@ public class DDPClientImpl { ...@@ -134,12 +127,12 @@ public class DDPClientImpl {
if ("pong".equals(msg)) { if ("pong".equals(msg)) {
if (response.isNull("id")) { if (response.isNull("id")) {
task.setResult(new DDPClientCallback.Ping(client, null)); task.setResult(new DDPClientCallback.Ping(client, null));
subscriptions.dispose(); disposables.clear();
} else { } else {
String _id = response.optString("id"); String _id = response.optString("id");
if (id.equals(_id)) { if (id.equals(_id)) {
task.setResult(new DDPClientCallback.Ping(client, id)); task.setResult(new DDPClientCallback.Ping(client, id));
subscriptions.dispose(); disposables.clear();
} }
} }
} }
...@@ -148,7 +141,7 @@ public class DDPClientImpl { ...@@ -148,7 +141,7 @@ public class DDPClientImpl {
) )
); );
addErrorCallback(subscriptions, task); addErrorCallback(disposables, task);
} else { } else {
task.trySetError(new DDPClientCallback.Closed(client)); task.trySetError(new DDPClientCallback.Closed(client));
} }
...@@ -160,9 +153,9 @@ public class DDPClientImpl { ...@@ -160,9 +153,9 @@ public class DDPClientImpl {
sendMessage("sub", json -> json.put("id", id).put("name", name).put("params", params)); sendMessage("sub", json -> json.put("id", id).put("name", name).put("params", params));
if (requested) { if (requested) {
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message) flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson) .map(DDPClientImpl::toJson)
...@@ -175,7 +168,7 @@ public class DDPClientImpl { ...@@ -175,7 +168,7 @@ public class DDPClientImpl {
String _id = ids.optString(i); String _id = ids.optString(i);
if (id.equals(_id)) { if (id.equals(_id)) {
task.setResult(new DDPSubscription.Ready(client, id)); task.setResult(new DDPSubscription.Ready(client, id));
subscriptions.dispose(); disposables.clear();
break; break;
} }
} }
...@@ -185,16 +178,15 @@ public class DDPClientImpl { ...@@ -185,16 +178,15 @@ public class DDPClientImpl {
if (id.equals(_id)) { if (id.equals(_id)) {
task.setError(new DDPSubscription.NoSub.Error(client, id, task.setError(new DDPSubscription.NoSub.Error(client, id,
response.optJSONObject("error"))); response.optJSONObject("error")));
subscriptions.dispose(); disposables.clear();
} }
} }
}, },
err -> { RCLog::e
}
) )
); );
addErrorCallback(subscriptions, task); addErrorCallback(disposables, task);
} else { } else {
task.trySetError(new DDPClientCallback.Closed(client)); task.trySetError(new DDPClientCallback.Closed(client));
} }
...@@ -206,9 +198,9 @@ public class DDPClientImpl { ...@@ -206,9 +198,9 @@ public class DDPClientImpl {
final boolean requested = sendMessage("unsub", json -> json.put("id", id)); final boolean requested = sendMessage("unsub", json -> json.put("id", id));
if (requested) { if (requested) {
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message) flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson) .map(DDPClientImpl::toJson)
...@@ -219,7 +211,7 @@ public class DDPClientImpl { ...@@ -219,7 +211,7 @@ public class DDPClientImpl {
String _id = response.optString("id"); String _id = response.optString("id");
if (id.equals(_id)) { if (id.equals(_id)) {
task.setResult(new DDPSubscription.NoSub(client, id)); task.setResult(new DDPSubscription.NoSub(client, id));
subscriptions.dispose(); disposables.clear();
} }
} }
}, },
...@@ -228,7 +220,7 @@ public class DDPClientImpl { ...@@ -228,7 +220,7 @@ public class DDPClientImpl {
) )
); );
addErrorCallback(subscriptions, task); addErrorCallback(disposables, task);
} else { } else {
task.trySetError(new DDPClientCallback.Closed(client)); task.trySetError(new DDPClientCallback.Closed(client));
} }
...@@ -241,9 +233,9 @@ public class DDPClientImpl { ...@@ -241,9 +233,9 @@ public class DDPClientImpl {
json -> json.put("method", method).put("params", params).put("id", id)); json -> json.put("method", method).put("params", params).put("id", id));
if (requested) { if (requested) {
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message) flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson) .map(DDPClientImpl::toJson)
...@@ -261,7 +253,7 @@ public class DDPClientImpl { ...@@ -261,7 +253,7 @@ public class DDPClientImpl {
String result = response.optString("result"); String result = response.optString("result");
task.setResult(new DDPClientCallback.RPC(client, id, result)); task.setResult(new DDPClientCallback.RPC(client, id, result));
} }
subscriptions.dispose(); disposables.clear();
} }
} }
}, },
...@@ -273,20 +265,20 @@ public class DDPClientImpl { ...@@ -273,20 +265,20 @@ public class DDPClientImpl {
) )
); );
addErrorCallback(subscriptions, task); addErrorCallback(disposables, task);
} else { } else {
task.trySetError(new DDPClientCallback.Closed(client)); task.trySetError(new DDPClientCallback.Closed(client));
} }
} }
private void subscribeBaseListeners() { private void subscribeBaseListeners() {
if (subscriptions != null && if (disposables != null &&
subscriptions.size() > 0 && !subscriptions.isDisposed()) { disposables.size() > 0 && !disposables.isDisposed()) {
return; return;
} }
subscriptions = new CompositeDisposable(); disposables = new CompositeDisposable();
subscriptions.add( disposables.add(
flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message) flowable.filter(callback -> callback instanceof RxWebSocketCallback.Message)
.map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString) .map(callback -> ((RxWebSocketCallback.Message) callback).responseBodyString)
.map(DDPClientImpl::toJson) .map(DDPClientImpl::toJson)
...@@ -301,8 +293,7 @@ public class DDPClientImpl { ...@@ -301,8 +293,7 @@ public class DDPClientImpl {
} }
} }
}, },
err -> { RCLog::e
}
) )
); );
} }
...@@ -351,8 +342,8 @@ public class DDPClientImpl { ...@@ -351,8 +342,8 @@ public class DDPClientImpl {
} }
public void unsubscribeBaseListeners() { public void unsubscribeBaseListeners() {
if (subscriptions.size() > 0 || !subscriptions.isDisposed()) { if (disposables.size() > 0 || !disposables.isDisposed()) {
subscriptions.dispose(); disposables.clear();
} }
} }
...@@ -363,13 +354,7 @@ public class DDPClientImpl { ...@@ -363,13 +354,7 @@ public class DDPClientImpl {
.cast(RxWebSocketCallback.Close.class) .cast(RxWebSocketCallback.Close.class)
.subscribe( .subscribe(
task::setResult, task::setResult,
err -> { err -> setTaskError(task, err)
if (err instanceof Exception) {
task.setError((Exception) err);
} else {
task.setError(new Exception(err));
}
}
); );
return task.getTask().onSuccessTask(_task -> { return task.getTask().onSuccessTask(_task -> {
...@@ -385,13 +370,7 @@ public class DDPClientImpl { ...@@ -385,13 +370,7 @@ public class DDPClientImpl {
.cast(RxWebSocketCallback.Failure.class) .cast(RxWebSocketCallback.Failure.class)
.subscribe( .subscribe(
task::setResult, task::setResult,
err -> { err -> setTaskError(task, err)
if (err instanceof Exception) {
task.setError((Exception) err);
} else {
task.setError(new Exception(err));
}
}
); );
return task.getTask().onSuccessTask(_task -> { return task.getTask().onSuccessTask(_task -> {
...@@ -414,19 +393,20 @@ public class DDPClientImpl { ...@@ -414,19 +393,20 @@ public class DDPClientImpl {
private void sendMessage(String msg, @Nullable JSONBuilder json, private void sendMessage(String msg, @Nullable JSONBuilder json,
TaskCompletionSource<?> taskForSetError) { TaskCompletionSource<?> taskForSetError) {
if (!sendMessage(msg, json)) { if (!sendMessage(msg, json)) {
if (taskForSetError != null) if (taskForSetError != null) {
taskForSetError.trySetError(new DDPClientCallback.Closed(client)); taskForSetError.trySetError(new DDPClientCallback.Closed(client));
} }
} }
}
private void addErrorCallback(CompositeDisposable subscriptions, TaskCompletionSource<?> task) { private void addErrorCallback(CompositeDisposable disposables, TaskCompletionSource<?> task) {
subscriptions.add( disposables.add(
flowable.subscribe( flowable.subscribe(
base -> { base -> {
}, },
err -> { err -> {
task.trySetError(new Exception(err)); task.trySetError(new Exception(err));
subscriptions.dispose(); disposables.clear();
} }
) )
); );
...@@ -440,6 +420,14 @@ public class DDPClientImpl { ...@@ -440,6 +420,14 @@ public class DDPClientImpl {
} }
} }
private void setTaskError(TaskCompletionSource<? extends RxWebSocketCallback.Base> task, Throwable throwable) {
if (throwable instanceof Exception) {
task.setError((Exception) throwable);
} else {
task.setError(new Exception(throwable));
}
}
private interface JSONBuilder { private interface JSONBuilder {
@NonNull @NonNull
JSONObject create(JSONObject root) throws JSONException; JSONObject create(JSONObject root) throws JSONException;
......
...@@ -162,6 +162,7 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -162,6 +162,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
addSubscription(subscription); addSubscription(subscription);
// Update to RxJava 2 (issue: https://github.com/RocketChat/Rocket.Chat.Android/issues/355)
addSubscription( addSubscription(
RxJavaInterop.toV2Observable(connectivityManagerApi.getServerConnectivityAsObservable()) RxJavaInterop.toV2Observable(connectivityManagerApi.getServerConnectivityAsObservable())
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
...@@ -171,8 +172,7 @@ public class MainPresenter extends BasePresenter<MainContract.View> ...@@ -171,8 +172,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
view.showConnecting(); view.showConnecting();
} }
}, },
err -> { Logger::report)
})
); );
} }
......
...@@ -38,6 +38,7 @@ import chat.rocket.persistence.realm.RealmStore; ...@@ -38,6 +38,7 @@ import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.internal.RealmSession; import chat.rocket.persistence.realm.models.internal.RealmSession;
import hu.akarnokd.rxjava.interop.RxJavaInterop; import hu.akarnokd.rxjava.interop.RxJavaInterop;
import hugo.weaving.DebugLog; import hugo.weaving.DebugLog;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import rx.Single; import rx.Single;
...@@ -254,28 +255,14 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -254,28 +255,14 @@ public class RocketChatWebSocketThread extends HandlerThread {
task.getResult().client.getOnFailureCallback().onSuccess(_task -> { task.getResult().client.getOnFailureCallback().onSuccess(_task -> {
ddpClient = null; ddpClient = null;
CompositeDisposable subscriptions = new CompositeDisposable(); CompositeDisposable disposables = new CompositeDisposable();
connectivityManager.notifyConnecting(hostname); connectivityManager.notifyConnecting(hostname);
subscriptions.add( disposables.add(
RxJavaInterop.toV2Single(connect().retry()) RxJavaInterop.toV2Single(connect().retry())
.observeOn(AndroidSchedulers.from(getLooper()))
.subscribe( .subscribe(
rocketChatWebSocketThread -> { rocketChatWebSocketThread -> forceRegisteringListeners(),
String roomId = rocketChatCache.getSelectedRoomId(); err -> logErrorAndDispose(err, disposables)
if (roomId != null) {
StreamRoomMessage streamRoomObserver = new StreamRoomMessage(
appContext,
hostname,
realmHelper,
ddpClientRef,
roomId
);
streamRoomObserver.register();
listeners.add(streamRoomObserver);
}
},
err -> {
subscriptions.dispose();
}
) )
); );
return null; return null;
...@@ -308,6 +295,22 @@ public class RocketChatWebSocketThread extends HandlerThread { ...@@ -308,6 +295,22 @@ public class RocketChatWebSocketThread extends HandlerThread {
})); }));
} }
private void logErrorAndDispose(Throwable throwable, CompositeDisposable disposables) {
RCLog.e(throwable);
disposables.clear();
}
private void forceRegisteringListeners() {
Iterator<Registrable> iterator = listeners.iterator();
while (iterator.hasNext()) {
Registrable registrable = iterator.next();
registrable.unregister();
iterator.remove();
}
listenersRegistered = false;
registerListeners();
}
@DebugLog @DebugLog
private Single<Boolean> connect() { private Single<Boolean> connect() {
return connectDDPClient() return connectDDPClient()
......
...@@ -118,10 +118,7 @@ public class MethodCallObserver extends AbstractModelObserver<MethodCall> { ...@@ -118,10 +118,7 @@ public class MethodCallObserver extends AbstractModelObserver<MethodCall> {
} else if (exception instanceof DDPClientCallback.RPC.Timeout) { } else if (exception instanceof DDPClientCallback.RPC.Timeout) {
// temp "fix"- we need to rewrite the connection layer a bit // temp "fix"- we need to rewrite the connection layer a bit
errMessage = "{\"message\": \"Connection Timeout\"}"; errMessage = "{\"message\": \"Connection Timeout\"}";
} /*else if (exception instanceof RxWebSocketCallback.Failure) { } else {
// temp "fix"- we need to rewrite the connection layer a bit
errMessage = "{\"message\": \"Connection Failure\"}";
}*/ else {
errMessage = exception.getMessage(); errMessage = exception.getMessage();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment