I am developing a project for which I must implement PUSH notifications with an atmosphere server. For this I am using a wasync client. In the original project, it is an Android client, however I isolated both the server code and the client to isolate the problem.
The problem itself, as indicated in the title, is that every time there is a connection drop with the server (for whatever reason), the client does not reconnect.
Software stack:
- Server: Atmosphere 2.4.2
- Server: Jersey 1.19
- Tomcat 7.0.62
- Client: wasync 2.1.2
For sending notifications I am using the channel model @Subscribe
/ @Publish
provided by Atmosphere. Although I've also tested with the model @Suspend
/ @Broadcast
and it has not worked for me either.
Server
@Path("metallica")
public class MetallicaService {
@GET
@Path("/suscripcion")
@Subscribe(value = "metallica", timeout = -1)
public String handshake() {
return null;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Track getTrackInJSON() {
Track track = new Track();
track.setTitle("Enter Sandman");
track.setSinger("Metallica");
return track;
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Publish("metallica")
public String createTrackInJSON(Track track) {
String result = "Metallica -- Track saved : " + track;
//return Response.status(201).entity(result).build();
return result;
}
}
Customer
public class MetallicaClient {
public static void main(String[] args) {
final Client client = ClientFactory.getDefault().newClient();
final RequestBuilder request = client.newRequestBuilder()
.method(Request.METHOD.GET)
.uri("http://localhost:8080/metallica/suscripcion")
.encoder(new Encoder<String, Reader>() { // Stream the request body
@Override
public Reader encode(String s) {
System.out.println("Encode: " + s);
return new StringReader(s);
}
})
.decoder(new Decoder<String, Reader>() {
@Override
public Reader decode(Event type, String s) {
if (type.equals(Event.MESSAGE)) {
System.out.println("---- Message received ----");
System.out.println("---- Date and time: " + Calendar.getInstance().getTime().toString() + " ----");
}
System.out.println("Decode: " + s);
return new StringReader(s);
}
})
.transport(Request.TRANSPORT.WEBSOCKET) // Try WebSocket
.transport(Request.TRANSPORT.LONG_POLLING); // Fallback to Long-Polling
final OptionsBuilder<DefaultOptions, DefaultOptionsBuilder> clientOptions = client.newOptionsBuilder()
.reconnect(true)
.reconnectAttempts(10)
.pauseBeforeReconnectInSeconds(10);
final Socket socket = client.create(clientOptions.build());
try {
socket.on("message", new Function<String>() {
@Override
public void on(String s) {
System.out.println("Respuesta: " + s);
}
}).on(new Function<IOException>() {
@Override
public void on(IOException e) {
e.printStackTrace();
}
}).on(Event.CLOSE.name(), new Function<String>() {
@Override
public void on(String s) {
System.out.println("Se ha perdido la conexión con el servidor.");
}
}).on(Event.REOPENED.name(), new Function<String>() {
@Override
public void on(String s) {
System.out.println("Reconexión.");
}
}).open(request.build());
} catch (IOException e) {
e.printStackTrace();
}
}
}
From the client I would like to highlight the following block of code, in which I am supposed to be configuring the reconnection (although at some point I must be messing up):
final OptionsBuilder<DefaultOptions, DefaultOptionsBuilder> clientOptions = client.newOptionsBuilder()
.reconnect(true)
.reconnectAttempts(10)
.pauseBeforeReconnectInSeconds(10);
final Socket socket = client.create(clientOptions.build());
To facilitate the work, I created a project on github: link