1616import okhttp3 .WebSocket ;
1717import okhttp3 .WebSocketListener ;
1818import okio .ByteString ;
19+ import rx .Completable ;
1920import rx .Observable ;
2021import rx .Subscriber ;
22+ import rx .subjects .PublishSubject ;
2123
2224/* package */ class OkHttpConnectionProvider implements ConnectionProvider {
2325
2830 private final OkHttpClient mOkHttpClient ;
2931
3032 private final List <Subscriber <? super LifecycleEvent >> mLifecycleSubscribers ;
33+ private final PublishSubject <LifecycleEvent > mLifecycleStream ;
3134 private final List <Subscriber <? super String >> mMessagesSubscribers ;
35+ private final PublishSubject <String > mMessagesStream ;
3236
3337 private WebSocket openedSocked ;
3438
3943 mLifecycleSubscribers = new ArrayList <>();
4044 mMessagesSubscribers = new ArrayList <>();
4145 mOkHttpClient = okHttpClient ;
46+
47+ mLifecycleStream = PublishSubject .create ();
48+ mMessagesStream = PublishSubject .create ();
4249 }
4350
4451 @ Override
4552 public Observable <String > messages () {
53+ createWebSocketConnection ();
54+ // By using Subjects, we can leave the tracking of Subscribers to Rx.
55+ // Additionally, server disconnection is now handled manually
56+ // (instead of trying to support disconnecting just by unsubscribing)
57+ return mMessagesStream ;
58+
59+ /*
4660 Observable<String> observable = Observable.<String>create(subscriber -> {
4761 mMessagesSubscribers.add(subscriber);
4862
@@ -61,6 +75,14 @@ public Observable<String> messages() {
6175
6276 createWebSocketConnection();
6377 return observable;
78+ */
79+ }
80+
81+ // this used to be done automatically whenever the "subscriber list" was empty
82+ // this way is more discrete
83+ @ Override
84+ public Completable disconnect () {
85+ return Completable .fromAction (() -> openedSocked .close (1000 , "" ));
6486 }
6587
6688 private void createWebSocketConnection () {
@@ -71,9 +93,9 @@ private void createWebSocketConnection() {
7193
7294 Request .Builder requestBuilder = new Request .Builder ()
7395 .url (mUri );
74-
96+
7597 addConnectionHeadersToBuilder (requestBuilder , mConnectHttpHeaders );
76-
98+
7799 openedSocked = mOkHttpClient .newWebSocket (requestBuilder .build (),
78100 new WebSocketListener () {
79101 @ Override
@@ -113,19 +135,24 @@ public void onFailure(WebSocket webSocket, Throwable t, Response response) {
113135
114136 @ Override
115137 public Observable <Void > send (String stompMessage ) {
116- return Observable .create (subscriber -> {
138+ // .create(onSubscribe) is deprecated because it's unsafe
139+ return Observable .fromCallable (() -> {
117140 if (openedSocked == null ) {
118- subscriber . onError ( new IllegalStateException ("Not connected yet" ) );
141+ throw new IllegalStateException ("Not connected yet" );
119142 } else {
120143 Log .d (TAG , "Send STOMP message: " + stompMessage );
121144 openedSocked .send (stompMessage );
122- subscriber . onCompleted () ;
145+ return null ;
123146 }
124147 });
125148 }
126149
127150 @ Override
128151 public Observable <LifecycleEvent > getLifecycleReceiver () {
152+ // Once again, opting to leave Subscriber tracking to Rx
153+ return mLifecycleStream ;
154+
155+ /*
129156 return Observable.<LifecycleEvent>create(subscriber -> {
130157 mLifecycleSubscribers.add(subscriber);
131158
@@ -135,6 +162,7 @@ public Observable<LifecycleEvent> getLifecycleReceiver() {
135162 if (iterator.next().isUnsubscribed()) iterator.remove();
136163 }
137164 });
165+ */
138166 }
139167
140168 private TreeMap <String , String > headersAsMap (Response response ) {
@@ -154,15 +182,24 @@ private void addConnectionHeadersToBuilder(Request.Builder requestBuilder, Map<S
154182
155183 private void emitLifecycleEvent (LifecycleEvent lifecycleEvent ) {
156184 Log .d (TAG , "Emit lifecycle event: " + lifecycleEvent .getType ().name ());
185+ // I know Subjects are discouraged, but I think this is way cleaner than before
186+ mLifecycleStream .onNext (lifecycleEvent );
187+
188+ /*
157189 for (Subscriber<? super LifecycleEvent> subscriber : mLifecycleSubscribers) {
158190 subscriber.onNext(lifecycleEvent);
159191 }
192+ */
160193 }
161194
162195 private void emitMessage (String stompMessage ) {
163196 Log .d (TAG , "Emit STOMP message: " + stompMessage );
197+ mMessagesStream .onNext (stompMessage );
198+
199+ /*
164200 for (Subscriber<? super String> subscriber : mMessagesSubscribers) {
165201 subscriber.onNext(stompMessage);
166202 }
203+ */
167204 }
168205}
0 commit comments