Skip to content

Commit 3880e3c

Browse files
Started on heartbeats, fixed example
1 parent 2067dfc commit 3880e3c

File tree

8 files changed

+61
-37
lines changed

8 files changed

+61
-37
lines changed

README.md

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
# STOMP protocol via WebSocket for Android
1+
# Websockets on Android
22

33
[![Release](https://jitpack.io/v/forresthopkinsa/StompProtocolAndroid.svg)](https://jitpack.io/#forresthopkinsa/StompProtocolAndroid)
44

55
## Overview
66

7-
**Note that this is a FORK of a project by NaikSoftware! This version is made to avoid using RetroLambda! (Scroll down to see other changes)**
7+
**Note that this is a FORK of a project by NaikSoftware! This version was originally made to avoid using RetroLambda.**
8+
9+
*(It now has [many other differences](#changes-in-this-fork).)*
810

911
This library provides support for [STOMP protocol](https://stomp.github.io/) over Websockets.
1012

11-
At now library works only as client for any backend that supports STOMP, such as
12-
NodeJS (e.g. using StompJS) or Spring Boot ([with WebSocket support](https://spring.io/guides/gs/messaging-stomp-websocket/)).
13+
Right now, the library works as a client for any backend that supports STOMP, such as
14+
Node.js (e.g. using StompJS) or Spring Boot ([with WebSocket support](https://spring.io/guides/gs/messaging-stomp-websocket/)).
1315

1416
Add library as gradle dependency (Versioning info [here](https://jitpack.io/#forresthopkinsa/StompProtocolAndroid)):
1517

@@ -28,12 +30,10 @@ You can use this library two ways:
2830
- Using the old JACK toolchain
2931
- If you have Java 8 compatiblity and Jack enabled, this library will work for you
3032
- Using the new Native Java 8 support
31-
- As of this writing, you must be using Android Studio Canary to use this feature.
33+
- As of this writing, you must be using Android Studio Beta to use this feature.
3234
- Has been tested in the following environments:
33-
- Beta 2, Gradle plugin v3.0.0-beta2
34-
- Beta 1, Gradle plugin v3.0.0-beta1
35-
- Canary 9, Gradle plugin v3.0.0-alpha9
36-
- Canary 8, Gradle plugin v3.0.0-alpha8
35+
- Beta 1-9, Gradle plugin v3.0.0-beta(1-9)
36+
- Canary 8-9, Gradle plugin v3.0.0-alpha(8-9)
3737
- It *should* work in all 3.0.0+ versions
3838
- You can find more info on the [Releases Page](https://github.com/forresthopkinsa/StompProtocolAndroid/releases)
3939

@@ -101,7 +101,7 @@ Check out the [upstream example server](https://github.com/NaikSoftware/stomp-pr
101101
});
102102

103103
client.send("/app/hello", "world").subscribe(
104-
aVoid -> Log.d(TAG, "Sent data!"),
104+
() -> Log.d(TAG, "Sent data!"),
105105
error -> Log.e(TAG, "Encountered error while sending data!", error)
106106
);
107107

@@ -131,8 +131,8 @@ client.lifecycle().subscribe(lifecycleEvent -> {
131131
Log.d(TAG, "Stomp connection opened");
132132
break;
133133
case CLOSED:
134-
Log.d(TAG, "Stomp connection closed");
135-
break;
134+
Log.d(TAG, "Stomp connection closed");
135+
break;
136136
case ERROR:
137137
Log.e(TAG, "Stomp connection error", lifecycleEvent.getException());
138138
break;
@@ -152,6 +152,16 @@ Yes, it's safe to pass `null` for either (or both) of the last two arguments. Th
152152

153153
Note: This method is only supported using OkHttp, not JWS.
154154

155+
**Heartbeating**
156+
157+
STOMP Heartbeat implementation is in progress. Right now, you can send a heartbeat request header upon initial websocket connect:
158+
159+
``` java
160+
// ask server to send us heartbeat every ten seconds
161+
client.setHeartbeat(10000);
162+
client.connect();
163+
```
164+
155165
**Support**
156166

157167
Right now, the library only supports sending and receiving messages. ACK messages and transactions are not implemented yet.
@@ -254,6 +264,9 @@ These are the possible changes you need to make to your code for this branch, if
254264
Log.i(TAG, "Received message: " + message.getPayload());
255265
});
256266
```
267+
- Rudimentary heartbeat mechanism
268+
- You can use `StompClient.setHeartbeat(ms interval)` to send a heartbeat header to the server
269+
- WIP; currently we don't deal with those heartbeats in any way other than printing them to console
257270
258271
## Additional Reading
259272

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ buildscript {
88
}
99
}
1010
dependencies {
11-
classpath 'com.android.tools.build:gradle:3.0.0-beta2'
11+
classpath 'com.android.tools.build:gradle:3.0.0-beta6'
1212
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
1313

1414
// NOTE: Do not place your application dependencies here; they belong

example-client/src/main/java/ua/naiksoftware/stompclientexample/MainActivity.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package ua.naiksoftware.stompclientexample;
22

3-
import android.support.v7.app.AppCompatActivity;
43
import android.os.Bundle;
4+
import android.support.v7.app.AppCompatActivity;
55
import android.support.v7.widget.LinearLayoutManager;
66
import android.support.v7.widget.RecyclerView;
77
import android.util.Log;
@@ -11,15 +11,12 @@
1111
import com.google.gson.Gson;
1212
import com.google.gson.GsonBuilder;
1313

14-
import org.java_websocket.WebSocket;
15-
1614
import java.text.SimpleDateFormat;
1715
import java.util.ArrayList;
1816
import java.util.Date;
1917
import java.util.List;
2018
import java.util.Locale;
2119

22-
import rx.Observable;
2320
import rx.Subscription;
2421
import rx.android.schedulers.AndroidSchedulers;
2522
import rx.schedulers.Schedulers;
@@ -56,7 +53,7 @@ public void disconnectStomp(View view) {
5653
}
5754

5855
public void connectStomp(View view) {
59-
mStompClient = Stomp.over(WebSocket.class, "ws://" + ANDROID_EMULATOR_LOCALHOST
56+
mStompClient = Stomp.over(Stomp.ConnectionProvider.JWS, "ws://" + ANDROID_EMULATOR_LOCALHOST
6057
+ ":" + RestClient.SERVER_PORT + "/example-endpoint/websocket");
6158

6259
mStompClient.lifecycle()
@@ -90,10 +87,10 @@ public void connectStomp(View view) {
9087

9188
public void sendEchoViaStomp(View v) {
9289
mStompClient.send("/topic/hello-msg-mapping", "Echo STOMP " + mTimeFormat.format(new Date()))
93-
.compose(applySchedulers())
94-
.subscribe(aVoid -> {
95-
Log.d(TAG, "STOMP echo send successfully");
96-
}, throwable -> {
90+
.unsubscribeOn(Schedulers.newThread())
91+
.subscribeOn(Schedulers.io())
92+
.observeOn(AndroidSchedulers.mainThread())
93+
.subscribe(() -> Log.d(TAG, "STOMP echo send successfully"), throwable -> {
9794
Log.e(TAG, "Error send STOMP echo", throwable);
9895
toast(throwable.getMessage());
9996
});
@@ -102,10 +99,10 @@ public void sendEchoViaStomp(View v) {
10299
public void sendEchoViaRest(View v) {
103100
mRestPingSubscription = RestClient.getInstance().getExampleRepository()
104101
.sendRestEcho("Echo REST " + mTimeFormat.format(new Date()))
105-
.compose(applySchedulers())
106-
.subscribe(aVoid -> {
107-
Log.d(TAG, "REST echo send successfully");
108-
}, throwable -> {
102+
.unsubscribeOn(Schedulers.newThread())
103+
.subscribeOn(Schedulers.io())
104+
.observeOn(AndroidSchedulers.mainThread())
105+
.subscribe(aVoid -> Log.d(TAG, "REST echo send successfully"), throwable -> {
109106
Log.e(TAG, "Error send REST echo", throwable);
110107
toast(throwable.getMessage());
111108
});
@@ -122,13 +119,6 @@ private void toast(String text) {
122119
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
123120
}
124121

125-
protected <T> Observable.Transformer<T, T> applySchedulers() {
126-
return rObservable -> rObservable
127-
.unsubscribeOn(Schedulers.newThread())
128-
.subscribeOn(Schedulers.io())
129-
.observeOn(AndroidSchedulers.mainThread());
130-
}
131-
132122
@Override
133123
protected void onDestroy() {
134124
mStompClient.disconnect();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Tue Aug 01 08:03:03 MST 2017
1+
#Tue Sep 05 08:26:08 MST 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

lib/src/main/java/ua/naiksoftware/stomp/AbstractConnectionProvider.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ private Completable initSocket() {
7676
.startWith(block);
7777
}
7878

79+
// Doesn't do anything at all, only here as a stub
80+
public Completable setHeartbeat(int ms) {
81+
return Completable.complete();
82+
}
83+
7984
/**
8085
* Most important method: connects to websocket and notifies program of messages.
8186
* <p>

lib/src/main/java/ua/naiksoftware/stomp/ConnectionProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ public interface ConnectionProvider {
3030
* Automatically emits Lifecycle.CLOSE
3131
*/
3232
Completable disconnect();
33+
34+
Completable setHeartbeat(int ms);
3335
}

lib/src/main/java/ua/naiksoftware/stomp/Stomp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static StompClient over(@NonNull ConnectionProvider connectionProvider, S
5050
public static StompClient over(@NonNull ConnectionProvider connectionProvider, String uri, @Nullable Map<String, String> connectHttpHeaders, @Nullable OkHttpClient okHttpClient) {
5151
if (connectionProvider == ConnectionProvider.JWS) {
5252
if (okHttpClient != null) {
53-
throw new IllegalArgumentException("You cannot pass a webSocketClient with 'org.java_websocket.WebSocket'. use null instead.");
53+
throw new IllegalArgumentException("You cannot pass an OkHttpClient when using JWS. Use null instead.");
5454
}
5555
return createStompClient(new WebSocketsConnectionProvider(uri, connectHttpHeaders));
5656
}

lib/src/main/java/ua/naiksoftware/stomp/client/StompClient.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class StompClient {
4444
private Parser parser;
4545
private Subscription lifecycleSub;
4646
private List<StompHeader> mHeaders;
47+
private int heartbeat;
4748

4849
public StompClient(ConnectionProvider connectionProvider) {
4950
mConnectionProvider = connectionProvider;
@@ -78,6 +79,18 @@ public void setParser(Parser parser) {
7879
this.parser = parser;
7980
}
8081

82+
/**
83+
* Sets the heartbeat interval to request from the server.
84+
* <p>
85+
* Not very useful yet, because we don't have any heartbeat logic on our side.
86+
*
87+
* @param ms heartbeat time in milliseconds
88+
*/
89+
public void setHeartbeat(int ms) {
90+
heartbeat = ms;
91+
mConnectionProvider.setHeartbeat(ms).subscribe();
92+
}
93+
8194
/**
8295
* Connect without reconnect if connected
8396
*/
@@ -86,7 +99,7 @@ public void connect() {
8699
}
87100

88101
/**
89-
* If already connected and reconnect=false - nope
102+
* Connect to websocket. If already connected, this will silently fail.
90103
*
91104
* @param _headers HTTP headers to send in the INITIAL REQUEST, i.e. during the protocol upgrade
92105
*/
@@ -100,6 +113,7 @@ public void connect(@Nullable List<StompHeader> _headers) {
100113
case OPENED:
101114
List<StompHeader> headers = new ArrayList<>();
102115
headers.add(new StompHeader(StompHeader.VERSION, SUPPORTED_VERSIONS));
116+
headers.add(new StompHeader(StompHeader.HEART_BEAT, "0," + heartbeat));
103117
if (_headers != null) headers.addAll(_headers);
104118
mConnectionProvider.send(new StompMessage(StompCommand.CONNECT, headers, null).compile())
105119
.subscribe();

0 commit comments

Comments
 (0)