Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
92ee59e8
Unverified
Commit
92ee59e8
authored
Nov 28, 2017
by
Rafael Kellermann Streit
Committed by
GitHub
Nov 28, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #586 from RocketChat/fix/indefinite-status-ticker
[FIX] Infinite status ticker
parents
61707e2d
cfa5323f
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
656 additions
and
679 deletions
+656
-679
DDPClient.java
...-ddp/src/main/java/chat/rocket/android_ddp/DDPClient.java
+5
-5
DDPClientImpl.java
.../src/main/java/chat/rocket/android_ddp/DDPClientImpl.java
+1
-1
MainActivity.java
.../main/java/chat/rocket/android/activity/MainActivity.java
+24
-45
MainPresenter.java
...main/java/chat/rocket/android/activity/MainPresenter.java
+217
-216
ConnectivityManagerApi.java
...a/chat/rocket/android/service/ConnectivityManagerApi.java
+9
-9
ConnectivityManagerInternal.java
...t/rocket/android/service/ConnectivityManagerInternal.java
+0
-4
RealmBasedConnectivityManager.java
...rocket/android/service/RealmBasedConnectivityManager.java
+249
-235
RocketChatService.java
...n/java/chat/rocket/android/service/RocketChatService.java
+122
-129
RocketChatWebSocketThread.java
...hat/rocket/android/service/RocketChatWebSocketThread.java
+11
-35
ServerConnectivity.java
.../java/chat/rocket/android/service/ServerConnectivity.java
+18
-0
No files found.
android-ddp/src/main/java/chat/rocket/android_ddp/DDPClient.java
View file @
92ee59e8
...
@@ -50,30 +50,30 @@ public class DDPClient {
...
@@ -50,30 +50,30 @@ public class DDPClient {
impl
=
new
DDPClientImpl
(
this
,
client
);
impl
=
new
DDPClientImpl
(
this
,
client
);
}
}
p
ublic
Task
<
DDPClientCallback
.
Connect
>
connect
(
String
url
,
String
session
)
{
p
rivate
Task
<
DDPClientCallback
.
Connect
>
connect
(
String
url
,
String
session
)
{
hostname
.
set
(
url
);
hostname
.
set
(
url
);
TaskCompletionSource
<
DDPClientCallback
.
Connect
>
task
=
new
TaskCompletionSource
<>();
TaskCompletionSource
<
DDPClientCallback
.
Connect
>
task
=
new
TaskCompletionSource
<>();
impl
.
connect
(
task
,
url
,
session
);
impl
.
connect
(
task
,
url
,
session
);
return
task
.
getTask
();
return
task
.
getTask
();
}
}
p
ublic
Task
<
DDPClientCallback
.
Ping
>
ping
(
@Nullable
String
id
)
{
p
rivate
Task
<
DDPClientCallback
.
Ping
>
ping
(
@Nullable
String
id
)
{
TaskCompletionSource
<
DDPClientCallback
.
Ping
>
task
=
new
TaskCompletionSource
<>();
TaskCompletionSource
<
DDPClientCallback
.
Ping
>
task
=
new
TaskCompletionSource
<>();
impl
.
ping
(
task
,
id
);
impl
.
ping
(
task
,
id
);
return
task
.
getTask
();
return
task
.
getTask
();
}
}
p
ublic
Maybe
<
DDPClientCallback
.
Base
>
doPing
(
@Nullable
String
id
)
{
p
rivate
Maybe
<
DDPClientCallback
.
Base
>
doPing
(
@Nullable
String
id
)
{
return
impl
.
ping
(
id
);
return
impl
.
ping
(
id
);
}
}
p
ublic
Task
<
DDPSubscription
.
Ready
>
sub
(
String
id
,
String
name
,
JSONArray
params
)
{
p
rivate
Task
<
DDPSubscription
.
Ready
>
sub
(
String
id
,
String
name
,
JSONArray
params
)
{
TaskCompletionSource
<
DDPSubscription
.
Ready
>
task
=
new
TaskCompletionSource
<>();
TaskCompletionSource
<
DDPSubscription
.
Ready
>
task
=
new
TaskCompletionSource
<>();
impl
.
sub
(
task
,
name
,
params
,
id
);
impl
.
sub
(
task
,
name
,
params
,
id
);
return
task
.
getTask
();
return
task
.
getTask
();
}
}
p
ublic
Task
<
DDPSubscription
.
NoSub
>
unsub
(
String
id
)
{
p
rivate
Task
<
DDPSubscription
.
NoSub
>
unsub
(
String
id
)
{
TaskCompletionSource
<
DDPSubscription
.
NoSub
>
task
=
new
TaskCompletionSource
<>();
TaskCompletionSource
<
DDPSubscription
.
NoSub
>
task
=
new
TaskCompletionSource
<>();
impl
.
unsub
(
task
,
id
);
impl
.
unsub
(
task
,
id
);
return
task
.
getTask
();
return
task
.
getTask
();
...
...
android-ddp/src/main/java/chat/rocket/android_ddp/DDPClientImpl.java
View file @
92ee59e8
...
@@ -52,7 +52,7 @@ public class DDPClientImpl {
...
@@ -52,7 +52,7 @@ public class DDPClientImpl {
}
}
}
}
public
void
connect
(
final
TaskCompletionSource
<
DDPClientCallback
.
Connect
>
task
,
final
String
url
,
/* package */
void
connect
(
final
TaskCompletionSource
<
DDPClientCallback
.
Connect
>
task
,
final
String
url
,
String
session
)
{
String
session
)
{
try
{
try
{
flowable
=
websocket
.
connect
(
url
).
autoConnect
(
2
);
flowable
=
websocket
.
connect
(
url
).
autoConnect
(
2
);
...
...
app/src/main/java/chat/rocket/android/activity/MainActivity.java
View file @
92ee59e8
...
@@ -47,9 +47,9 @@ import hugo.weaving.DebugLog;
...
@@ -47,9 +47,9 @@ import hugo.weaving.DebugLog;
*/
*/
public
class
MainActivity
extends
AbstractAuthedActivity
implements
MainContract
.
View
{
public
class
MainActivity
extends
AbstractAuthedActivity
implements
MainContract
.
View
{
private
RoomToolbar
toolbar
;
private
RoomToolbar
toolbar
;
private
StatusTicker
statusTicker
;
private
SlidingPaneLayout
pane
;
private
SlidingPaneLayout
pane
;
private
MainContract
.
Presenter
presenter
;
private
MainContract
.
Presenter
presenter
;
private
volatile
Snackbar
statusTicker
;
@Override
@Override
public
int
getLayoutContainerForFragment
()
{
public
int
getLayoutContainerForFragment
()
{
...
@@ -61,7 +61,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
...
@@ -61,7 +61,6 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
super
.
onCreate
(
savedInstanceState
);
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
setContentView
(
R
.
layout
.
activity_main
);
toolbar
=
findViewById
(
R
.
id
.
activity_main_toolbar
);
toolbar
=
findViewById
(
R
.
id
.
activity_main_toolbar
);
statusTicker
=
new
StatusTicker
();
pane
=
findViewById
(
R
.
id
.
sliding_pane
);
pane
=
findViewById
(
R
.
id
.
sliding_pane
);
setupToolbar
();
setupToolbar
();
}
}
...
@@ -95,6 +94,8 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
...
@@ -95,6 +94,8 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
if
(
presenter
!=
null
)
{
if
(
presenter
!=
null
)
{
presenter
.
release
();
presenter
.
release
();
}
}
// Dismiss any status ticker
if
(
statusTicker
!=
null
)
statusTicker
.
dismiss
();
super
.
onPause
();
super
.
onPause
();
}
}
...
@@ -245,28 +246,36 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
...
@@ -245,28 +246,36 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
@Override
@Override
public
void
showLoginScreen
()
{
public
void
showLoginScreen
()
{
LaunchUtil
.
showLoginActivity
(
this
,
hostname
);
LaunchUtil
.
showLoginActivity
(
this
,
hostname
);
s
tatusTicker
.
updateStatus
(
StatusTicker
.
STATUS_DISMISS
,
null
);
s
howConnectionOk
(
);
}
}
@Override
@Override
public
void
showConnectionError
()
{
public
synchronized
void
showConnectionError
()
{
statusTicker
.
updateStatus
(
StatusTicker
.
STATUS_CONNECTION_ERROR
,
dismissStatusTickerIfShowing
();
Snackbar
.
make
(
findViewById
(
getLayoutContainerForFragment
()),
statusTicker
=
Snackbar
.
make
(
findViewById
(
getLayoutContainerForFragment
()),
R
.
string
.
fragment_retry_login_error_title
,
Snackbar
.
LENGTH_INDEFINITE
)
R
.
string
.
fragment_retry_login_error_title
,
Snackbar
.
LENGTH_INDEFINITE
)
.
setAction
(
R
.
string
.
fragment_retry_login_retry_title
,
view
->
.
setAction
(
R
.
string
.
fragment_retry_login_retry_title
,
view
->
ConnectivityManager
.
getInstance
(
getApplicationContext
()).
keepAliveServer
()));
ConnectivityManager
.
getInstance
(
getApplicationContext
()).
keepAliveServer
());
statusTicker
.
show
();
}
}
@Override
@Override
public
void
showConnecting
()
{
public
synchronized
void
showConnecting
()
{
statusTicker
.
updateStatus
(
StatusTicker
.
STATUS_TOKEN_LOGIN
,
dismissStatusTickerIfShowing
();
Snackbar
.
make
(
findViewById
(
getLayoutContainerForFragment
()),
statusTicker
=
Snackbar
.
make
(
findViewById
(
getLayoutContainerForFragment
()),
R
.
string
.
server_config_activity_authenticating
,
Snackbar
.
LENGTH_INDEFINITE
));
R
.
string
.
server_config_activity_authenticating
,
Snackbar
.
LENGTH_INDEFINITE
);
statusTicker
.
show
();
}
}
@Override
@Override
public
void
showConnectionOk
()
{
public
synchronized
void
showConnectionOk
()
{
statusTicker
.
updateStatus
(
StatusTicker
.
STATUS_DISMISS
,
null
);
dismissStatusTickerIfShowing
();
}
private
void
dismissStatusTickerIfShowing
()
{
if
(
statusTicker
!=
null
)
{
statusTicker
.
dismiss
();
}
}
}
@Override
@Override
...
@@ -349,34 +358,4 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
...
@@ -349,34 +358,4 @@ public class MainActivity extends AbstractAuthedActivity implements MainContract
public
void
beforeLogoutCleanUp
()
{
public
void
beforeLogoutCleanUp
()
{
presenter
.
beforeLogoutCleanUp
();
presenter
.
beforeLogoutCleanUp
();
}
}
//TODO: consider this class to define in layouthelper for more complicated operation.
private
static
class
StatusTicker
{
static
final
int
STATUS_DISMISS
=
0
;
static
final
int
STATUS_CONNECTION_ERROR
=
1
;
static
final
int
STATUS_TOKEN_LOGIN
=
2
;
private
int
status
;
private
Snackbar
snackbar
;
StatusTicker
()
{
status
=
STATUS_DISMISS
;
}
void
updateStatus
(
int
status
,
Snackbar
snackbar
)
{
if
(
status
==
this
.
status
)
{
return
;
}
this
.
status
=
status
;
if
(
this
.
snackbar
!=
null
)
{
this
.
snackbar
.
dismiss
();
}
if
(
status
!=
STATUS_DISMISS
)
{
this
.
snackbar
=
snackbar
;
if
(
this
.
snackbar
!=
null
)
{
this
.
snackbar
.
show
();
}
}
}
}
}
}
app/src/main/java/chat/rocket/android/activity/MainPresenter.java
View file @
92ee59e8
...
@@ -220,6 +220,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
...
@@ -220,6 +220,7 @@ public class MainPresenter extends BasePresenter<MainContract.View>
private
void
subscribeToNetworkChanges
()
{
private
void
subscribeToNetworkChanges
()
{
Disposable
disposable
=
connectivityManagerApi
.
getServerConnectivityAsObservable
()
Disposable
disposable
=
connectivityManagerApi
.
getServerConnectivityAsObservable
()
.
distinctUntilChanged
()
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
.
subscribe
(
connectivity
->
{
connectivity
->
{
...
...
app/src/main/java/chat/rocket/android/service/ConnectivityManagerApi.java
View file @
92ee59e8
...
@@ -6,7 +6,7 @@ import android.support.annotation.Nullable;
...
@@ -6,7 +6,7 @@ import android.support.annotation.Nullable;
import
java.util.List
;
import
java.util.List
;
import
chat.rocket.core.models.ServerInfo
;
import
chat.rocket.core.models.ServerInfo
;
import
io.reactivex.
Observ
able
;
import
io.reactivex.
Flow
able
;
import
io.reactivex.Single
;
import
io.reactivex.Single
;
/**
/**
...
@@ -23,7 +23,7 @@ public interface ConnectivityManagerApi {
...
@@ -23,7 +23,7 @@ public interface ConnectivityManagerApi {
List
<
ServerInfo
>
getServerList
();
List
<
ServerInfo
>
getServerList
();
Observ
able
<
ServerConnectivity
>
getServerConnectivityAsObservable
();
Flow
able
<
ServerConnectivity
>
getServerConnectivityAsObservable
();
int
getConnectivityState
(
@NonNull
String
hostname
);
int
getConnectivityState
(
@NonNull
String
hostname
);
...
...
app/src/main/java/chat/rocket/android/service/ConnectivityManagerInternal.java
View file @
92ee59e8
...
@@ -8,10 +8,6 @@ import chat.rocket.core.models.ServerInfo;
...
@@ -8,10 +8,6 @@ import chat.rocket.core.models.ServerInfo;
* interfaces used for RocketChatService and RocketChatwebSocketThread.
* interfaces used for RocketChatService and RocketChatwebSocketThread.
*/
*/
/*package*/
interface
ConnectivityManagerInternal
{
/*package*/
interface
ConnectivityManagerInternal
{
int
REASON_CLOSED_BY_USER
=
101
;
int
REASON_NETWORK_ERROR
=
102
;
int
REASON_SERVER_ERROR
=
103
;
int
REASON_UNKNOWN
=
104
;
void
resetConnectivityStateList
();
void
resetConnectivityStateList
();
...
...
app/src/main/java/chat/rocket/android/service/RealmBasedConnectivityManager.java
View file @
92ee59e8
...
@@ -21,10 +21,11 @@ import chat.rocket.android_ddp.DDPClient;
...
@@ -21,10 +21,11 @@ import chat.rocket.android_ddp.DDPClient;
import
chat.rocket.core.models.ServerInfo
;
import
chat.rocket.core.models.ServerInfo
;
import
chat.rocket.persistence.realm.models.RealmBasedServerInfo
;
import
chat.rocket.persistence.realm.models.RealmBasedServerInfo
;
import
hugo.weaving.DebugLog
;
import
hugo.weaving.DebugLog
;
import
io.reactivex.Observable
;
import
io.reactivex.BackpressureStrategy
;
import
io.reactivex.Flowable
;
import
io.reactivex.Single
;
import
io.reactivex.Single
;
import
io.reactivex.schedulers.Schedulers
;
import
io.reactivex.schedulers.Schedulers
;
import
io.reactivex.subjects.
Publish
Subject
;
import
io.reactivex.subjects.
Behavior
Subject
;
/**
/**
* Connectivity management implementation.
* Connectivity management implementation.
...
@@ -32,7 +33,7 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -32,7 +33,7 @@ import io.reactivex.subjects.PublishSubject;
/*package*/
class
RealmBasedConnectivityManager
/*package*/
class
RealmBasedConnectivityManager
implements
ConnectivityManagerApi
,
ConnectivityManagerInternal
{
implements
ConnectivityManagerApi
,
ConnectivityManagerInternal
{
private
volatile
ConcurrentHashMap
<
String
,
Integer
>
serverConnectivityList
=
new
ConcurrentHashMap
<>();
private
volatile
ConcurrentHashMap
<
String
,
Integer
>
serverConnectivityList
=
new
ConcurrentHashMap
<>();
private
final
PublishSubject
<
ServerConnectivity
>
connectivitySubject
=
PublishSubject
.
create
(
);
private
volatile
BehaviorSubject
<
ServerConnectivity
>
connectivitySubject
=
BehaviorSubject
.
createDefault
(
ServerConnectivity
.
CONNECTED
);
private
Context
appContext
;
private
Context
appContext
;
private
final
ServiceConnection
serviceConnection
=
new
ServiceConnection
()
{
private
final
ServiceConnection
serviceConnection
=
new
ServiceConnection
()
{
@Override
@Override
...
@@ -79,7 +80,10 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -79,7 +80,10 @@ import io.reactivex.subjects.PublishSubject;
}
}
connectToServerIfNeeded
(
hostname
,
true
/* force connect */
)
connectToServerIfNeeded
(
hostname
,
true
/* force connect */
)
.
subscribeOn
(
Schedulers
.
io
())
.
subscribeOn
(
Schedulers
.
io
())
.
subscribe
(
_val
->
{
.
subscribe
(
connected
->
{
if
(!
connected
)
{
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_NETWORK_ERROR
);
}
},
error
->
{
},
error
->
{
RCLog
.
e
(
error
);
RCLog
.
e
(
error
);
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_NETWORK_ERROR
);
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_NETWORK_ERROR
);
...
@@ -94,7 +98,7 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -94,7 +98,7 @@ import io.reactivex.subjects.PublishSubject;
serverConnectivityList
.
put
(
hostname
,
ServerConnectivity
.
STATE_DISCONNECTED
);
serverConnectivityList
.
put
(
hostname
,
ServerConnectivity
.
STATE_DISCONNECTED
);
}
}
connectToServerIfNeeded
(
hostname
,
false
)
connectToServerIfNeeded
(
hostname
,
false
)
.
subscribe
(
_val
->
{
.
subscribe
(
connected
->
{
},
RCLog:
:
e
);
},
RCLog:
:
e
);
}
}
...
@@ -135,7 +139,9 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -135,7 +139,9 @@ import io.reactivex.subjects.PublishSubject;
@DebugLog
@DebugLog
@Override
@Override
public
void
notifyConnectionEstablished
(
String
hostname
,
String
session
)
{
public
void
notifyConnectionEstablished
(
String
hostname
,
String
session
)
{
if
(
session
!=
null
)
{
RealmBasedServerInfo
.
updateSession
(
hostname
,
session
);
RealmBasedServerInfo
.
updateSession
(
hostname
,
session
);
}
serverConnectivityList
.
put
(
hostname
,
ServerConnectivity
.
STATE_CONNECTED
);
serverConnectivityList
.
put
(
hostname
,
ServerConnectivity
.
STATE_CONNECTED
);
connectivitySubject
.
onNext
(
connectivitySubject
.
onNext
(
new
ServerConnectivity
(
hostname
,
ServerConnectivity
.
STATE_CONNECTED
));
new
ServerConnectivity
(
hostname
,
ServerConnectivity
.
STATE_CONNECTED
));
...
@@ -158,8 +164,8 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -158,8 +164,8 @@ import io.reactivex.subjects.PublishSubject;
}
}
@Override
@Override
public
Observ
able
<
ServerConnectivity
>
getServerConnectivityAsObservable
()
{
public
Flow
able
<
ServerConnectivity
>
getServerConnectivityAsObservable
()
{
return
Observable
.
concat
(
Observable
.
fromIterable
(
getCurrentConnectivityList
()),
connectivitySubject
);
return
connectivitySubject
.
toFlowable
(
BackpressureStrategy
.
LATEST
);
}
}
@Override
@Override
...
@@ -185,10 +191,12 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -185,10 +191,12 @@ import io.reactivex.subjects.PublishSubject;
}
}
if
(
connectivity
==
ServerConnectivity
.
STATE_DISCONNECTED
)
{
if
(
connectivity
==
ServerConnectivity
.
STATE_DISCONNECTED
)
{
notifyConnecting
(
hostname
);
//
notifyConnecting(hostname);
}
}
return
connectToServer
(
hostname
);
return
connectToServer
(
hostname
)
.
retry
(
exception
->
exception
instanceof
ThreadLooperNotPreparedException
)
.
onErrorResumeNext
(
Single
.
just
(
false
));
});
});
}
}
...
@@ -257,7 +265,7 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -257,7 +265,7 @@ import io.reactivex.subjects.PublishSubject;
if
(
serviceInterface
!=
null
)
{
if
(
serviceInterface
!=
null
)
{
return
serviceInterface
.
ensureConnectionToServer
(
hostname
);
return
serviceInterface
.
ensureConnectionToServer
(
hostname
);
}
else
{
}
else
{
return
Single
.
error
(
new
IllegalState
Exception
(
"not prepared"
));
return
Single
.
error
(
new
ThreadLooperNotPrepared
Exception
(
"not prepared"
));
}
}
});
});
}
}
...
@@ -278,4 +286,10 @@ import io.reactivex.subjects.PublishSubject;
...
@@ -278,4 +286,10 @@ import io.reactivex.subjects.PublishSubject;
}
}
});
});
}
}
private
static
class
ThreadLooperNotPreparedException
extends
IllegalStateException
{
ThreadLooperNotPreparedException
(
String
message
)
{
super
(
message
);
}
}
}
}
\ No newline at end of file
app/src/main/java/chat/rocket/android/service/RocketChatService.java
View file @
92ee59e8
...
@@ -38,7 +38,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
...
@@ -38,7 +38,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
/**
/**
* ensure RocketChatService alive.
* ensure RocketChatService alive.
*/
*/
/*package*/
static
void
keepAlive
(
Context
context
)
{
/*package*/
static
void
keepAlive
(
Context
context
)
{
context
.
startService
(
new
Intent
(
context
,
RocketChatService
.
class
));
context
.
startService
(
new
Intent
(
context
,
RocketChatService
.
class
));
}
}
...
@@ -69,11 +69,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
...
@@ -69,11 +69,7 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
@Override
@Override
public
Single
<
Boolean
>
ensureConnectionToServer
(
String
hostname
)
{
//called via binder.
public
Single
<
Boolean
>
ensureConnectionToServer
(
String
hostname
)
{
//called via binder.
return
getOrCreateWebSocketThread
(
hostname
)
return
getOrCreateWebSocketThread
(
hostname
)
.
doOnError
(
err
->
{
.
flatMap
(
RocketChatWebSocketThread:
:
keepAlive
);
err
.
printStackTrace
();
currentWebSocketThread
=
null
;
})
.
flatMap
(
webSocketThreads
->
webSocketThreads
.
keepAlive
());
}
}
@Override
@Override
...
@@ -109,12 +105,9 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
...
@@ -109,12 +105,9 @@ public class RocketChatService extends Service implements ConnectivityServiceInt
return
Single
.
just
(
currentWebSocketThread
);
return
Single
.
just
(
currentWebSocketThread
);
}
}
connectivityManager
.
notifyConnecting
(
hostname
);
if
(
currentWebSocketThread
!=
null
)
{
if
(
currentWebSocketThread
!=
null
)
{
return
currentWebSocketThread
.
terminate
()
return
currentWebSocketThread
.
terminate
()
.
doAfterTerminate
(()
->
currentWebSocketThread
=
null
)
.
doAfterTerminate
(()
->
currentWebSocketThread
=
null
)
.
doOnError
(
RCLog:
:
e
)
.
flatMap
(
terminated
->
.
flatMap
(
terminated
->
RocketChatWebSocketThread
.
getStarted
(
getApplicationContext
(),
hostname
)
RocketChatWebSocketThread
.
getStarted
(
getApplicationContext
(),
hostname
)
.
doOnSuccess
(
thread
->
{
.
doOnSuccess
(
thread
->
{
...
...
app/src/main/java/chat/rocket/android/service/RocketChatWebSocketThread.java
View file @
92ee59e8
...
@@ -76,26 +76,6 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -76,26 +76,6 @@ public class RocketChatWebSocketThread extends HandlerThread {
private
final
CompositeDisposable
reconnectDisposable
=
new
CompositeDisposable
();
private
final
CompositeDisposable
reconnectDisposable
=
new
CompositeDisposable
();
private
boolean
listenersRegistered
;
private
boolean
listenersRegistered
;
private
static
class
KeepAliveTimer
{
private
long
lastTime
;
private
final
long
thresholdMs
;
public
KeepAliveTimer
(
long
thresholdMs
)
{
this
.
thresholdMs
=
thresholdMs
;
lastTime
=
System
.
currentTimeMillis
();
}
public
boolean
shouldCheckPrecisely
()
{
return
lastTime
+
thresholdMs
<
System
.
currentTimeMillis
();
}
public
void
update
()
{
lastTime
=
System
.
currentTimeMillis
();
}
}
private
final
KeepAliveTimer
keepAliveTimer
=
new
KeepAliveTimer
(
20000
);
private
RocketChatWebSocketThread
(
Context
appContext
,
String
hostname
)
{
private
RocketChatWebSocketThread
(
Context
appContext
,
String
hostname
)
{
super
(
"RC_thread_"
+
hostname
);
super
(
"RC_thread_"
+
hostname
);
this
.
appContext
=
appContext
;
this
.
appContext
=
appContext
;
...
@@ -108,7 +88,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -108,7 +88,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
* build new Thread.
* build new Thread.
*/
*/
@DebugLog
@DebugLog
public
static
Single
<
RocketChatWebSocketThread
>
getStarted
(
Context
appContext
,
String
hostname
)
{
/* package */
static
Single
<
RocketChatWebSocketThread
>
getStarted
(
Context
appContext
,
String
hostname
)
{
return
Single
.<
RocketChatWebSocketThread
>
create
(
objectSingleEmitter
->
{
return
Single
.<
RocketChatWebSocketThread
>
create
(
objectSingleEmitter
->
{
new
RocketChatWebSocketThread
(
appContext
,
hostname
)
{
new
RocketChatWebSocketThread
(
appContext
,
hostname
)
{
@Override
@Override
...
@@ -148,7 +128,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -148,7 +128,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
* terminate WebSocket thread.
* terminate WebSocket thread.
*/
*/
@DebugLog
@DebugLog
public
Single
<
Boolean
>
terminate
()
{
/* package */
Single
<
Boolean
>
terminate
()
{
if
(
isAlive
())
{
if
(
isAlive
())
{
return
Single
.
create
(
emitter
->
{
return
Single
.
create
(
emitter
->
{
new
Handler
(
getLooper
()).
post
(()
->
{
new
Handler
(
getLooper
()).
post
(()
->
{
...
@@ -181,7 +161,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -181,7 +161,7 @@ public class RocketChatWebSocketThread extends HandlerThread {
* synchronize the state of the thread with ServerConfig.
* synchronize the state of the thread with ServerConfig.
*/
*/
@DebugLog
@DebugLog
public
Single
<
Boolean
>
keepAlive
()
{
/* package */
Single
<
Boolean
>
keepAlive
()
{
return
checkIfConnectionAlive
()
return
checkIfConnectionAlive
()
.
flatMap
(
alive
->
alive
?
Single
.
just
(
true
)
:
connectWithExponentialBackoff
());
.
flatMap
(
alive
->
alive
?
Single
.
just
(
true
)
:
connectWithExponentialBackoff
());
}
}
...
@@ -192,11 +172,6 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -192,11 +172,6 @@ public class RocketChatWebSocketThread extends HandlerThread {
return
Single
.
just
(
false
);
return
Single
.
just
(
false
);
}
}
if
(!
keepAliveTimer
.
shouldCheckPrecisely
())
{
return
Single
.
just
(
true
);
}
keepAliveTimer
.
update
();
return
Single
.
create
(
emitter
->
{
return
Single
.
create
(
emitter
->
{
new
Thread
()
{
new
Thread
()
{
@Override
@Override
...
@@ -207,9 +182,8 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -207,9 +182,8 @@ public class RocketChatWebSocketThread extends HandlerThread {
RCLog
.
e
(
error
);
RCLog
.
e
(
error
);
connectivityManager
.
notifyConnectionLost
(
connectivityManager
.
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_CLOSED_BY_USER
);
hostname
,
DDPClient
.
REASON_CLOSED_BY_USER
);
emitter
.
on
Error
(
error
);
emitter
.
on
Success
(
false
);
}
else
{
}
else
{
keepAliveTimer
.
update
();
emitter
.
onSuccess
(
true
);
emitter
.
onSuccess
(
true
);
}
}
return
null
;
return
null
;
...
@@ -245,11 +219,11 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -245,11 +219,11 @@ public class RocketChatWebSocketThread extends HandlerThread {
return
;
return
;
}
}
RCLog
.
d
(
"DDPClient#connect"
);
RCLog
.
d
(
"DDPClient#connect"
);
connectivityManager
.
notifyConnecting
(
hostname
);
DDPClient
.
get
().
connect
(
hostname
,
info
.
getSession
(),
info
.
isSecure
())
DDPClient
.
get
().
connect
(
hostname
,
info
.
getSession
(),
info
.
isSecure
())
.
onSuccessTask
(
task
->
{
.
onSuccessTask
(
task
->
{
final
String
newSession
=
task
.
getResult
().
session
;
final
String
newSession
=
task
.
getResult
().
session
;
connectivityManager
.
notifyConnectionEstablished
(
hostname
,
newSession
);
connectivityManager
.
notifyConnectionEstablished
(
hostname
,
newSession
);
// handling WebSocket#onClose() callback.
// handling WebSocket#onClose() callback.
task
.
getResult
().
client
.
getOnCloseCallback
().
onSuccess
(
_task
->
{
task
.
getResult
().
client
.
getOnCloseCallback
().
onSuccess
(
_task
->
{
RxWebSocketCallback
.
Close
result
=
_task
.
getResult
();
RxWebSocketCallback
.
Close
result
=
_task
.
getResult
();
...
@@ -292,18 +266,18 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -292,18 +266,18 @@ public class RocketChatWebSocketThread extends HandlerThread {
return
;
return
;
}
}
forceInvalidateTokens
();
forceInvalidateTokens
();
connectivityManager
.
notifyConnecting
(
hostname
);
reconnectDisposable
.
add
(
reconnectDisposable
.
add
(
connectWithExponentialBackoff
()
connectWithExponentialBackoff
()
.
subscribe
(
connected
->
{
.
subscribe
(
connected
->
{
if
(!
connected
)
{
if
(!
connected
)
{
connectivityManager
.
notifyConnecting
(
hostname
);
connectivityManager
.
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_NETWORK_ERROR
);
}
}
reconnectDisposable
.
clear
();
reconnectDisposable
.
clear
();
},
error
->
{
},
error
->
{
logErrorAndUnsubscribe
(
reconnectDisposable
,
error
);
connectivityManager
.
notifyConnectionLost
(
hostname
,
connectivityManager
.
notifyConnectionLost
(
hostname
,
DDPClient
.
REASON_NETWORK_ERROR
);
DDPClient
.
REASON_NETWORK_ERROR
);
logErrorAndUnsubscribe
(
reconnectDisposable
,
error
);
}
}
)
)
);
);
...
@@ -315,7 +289,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
...
@@ -315,7 +289,9 @@ public class RocketChatWebSocketThread extends HandlerThread {
}
}
private
Single
<
Boolean
>
connectWithExponentialBackoff
()
{
private
Single
<
Boolean
>
connectWithExponentialBackoff
()
{
return
connect
().
retryWhen
(
RxHelper
.
exponentialBackoff
(
3
,
500
,
TimeUnit
.
MILLISECONDS
));
return
connect
()
.
retryWhen
(
RxHelper
.
exponentialBackoff
(
1
,
250
,
TimeUnit
.
MILLISECONDS
))
.
onErrorResumeNext
(
Single
.
just
(
false
));
}
}
@DebugLog
@DebugLog
...
...
app/src/main/java/chat/rocket/android/service/ServerConnectivity.java
View file @
92ee59e8
...
@@ -4,10 +4,13 @@ package chat.rocket.android.service;
...
@@ -4,10 +4,13 @@ package chat.rocket.android.service;
* pair with server's hostname and its connectivity state.
* pair with server's hostname and its connectivity state.
*/
*/
public
class
ServerConnectivity
{
public
class
ServerConnectivity
{
public
static
final
int
STATE_CONNECTED
=
1
;
public
static
final
int
STATE_CONNECTED
=
1
;
public
static
final
int
STATE_DISCONNECTED
=
2
;
public
static
final
int
STATE_DISCONNECTED
=
2
;
public
static
final
int
STATE_CONNECTING
=
3
;
public
static
final
int
STATE_CONNECTING
=
3
;
/*package*/
static
final
int
STATE_DISCONNECTING
=
4
;
/*package*/
static
final
int
STATE_DISCONNECTING
=
4
;
public
static
final
ServerConnectivity
CONNECTED
=
new
ServerConnectivity
(
null
,
STATE_CONNECTED
);
public
final
String
hostname
;
public
final
String
hostname
;
public
final
int
state
;
public
final
int
state
;
...
@@ -25,6 +28,21 @@ public class ServerConnectivity {
...
@@ -25,6 +28,21 @@ public class ServerConnectivity {
this
.
code
=
code
;
this
.
code
=
code
;
}
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
ServerConnectivity
that
=
(
ServerConnectivity
)
o
;
return
state
==
that
.
state
;
}
@Override
public
int
hashCode
()
{
return
state
;
}
/**
/**
* This exception should be thrown when connection is lost during waiting for CONNECTED.
* This exception should be thrown when connection is lost during waiting for CONNECTED.
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment