Skip to content

Commit

Permalink
Server now pings clients instead of vice versa when checking to remov…
Browse files Browse the repository at this point in the history
…e clients from jam.
  • Loading branch information
JayThomason committed May 15, 2014
1 parent ca1156f commit 7366ce8
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 49 deletions.
8 changes: 8 additions & 0 deletions src/com/stanford/tutti/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ public void removeAllFrom(Client clientToRemove,
client.get(url, responseHandler);
}

/*
* Sends a ping message to the client to check if it is still there.
*/
public void ping(AsyncHttpResponseHandler responseHandler) {
String url = getUrl("/ping", "");
client.get(url, responseHandler);
}

private String getUrl(String path, String query) {
return "http://" + ipAddress + ":" + port + path + query;
}
Expand Down
117 changes: 71 additions & 46 deletions src/com/stanford/tutti/Jam.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Message;
import android.os.PowerManager;

public class Jam {
ArrayList<Song> songList;
Expand Down Expand Up @@ -76,8 +78,10 @@ public void addClient(Client client) {
synchronized (clientSet) {
clientSet.add(client);
}
usernameMap.put(client.getIpAddress(), client.getUsername());
keepAliveTimestampMap.put(client.getIpAddress(), System.currentTimeMillis() / 1000L);
usernameMap.put(client.getIpAddress(), client.getUsername());
synchronized (keepAliveTimestampMap) {
keepAliveTimestampMap.put(client.getIpAddress(), System.currentTimeMillis() / 1000L);
}
}

public boolean checkMaster() {
Expand Down Expand Up @@ -179,22 +183,22 @@ public void changeSongIndexInJam(int from, int to) {
}
currentSong = songList.get(currentSongIndex);
}

public void shuffle() {
if (!isShuffled()) {
System.out.println("SHUFFLING");
g.db.shuffleJam(currentSongIndex, songList.size() - 1);
isShuffled = true;
// Add a helper to just reload song list from jam database.
} else {

}
}

public void unShuffle() {
isShuffled = false;
}

public boolean isShuffled() {
return isShuffled;
}
Expand Down Expand Up @@ -433,12 +437,19 @@ public void run() {
if (clientKeepAlive.get()) {
client.get(url, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if (statusCode == 200) {
System.out.println("successfully sent keep alive to master");
}
else {
System.out.println("failed to send keep alive to master!");
}
} @Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
// TODO: in this case we want to display some notification to the user and exit the jam
System.out.println("failed keepAlive to master...");
}
});
System.out.println("send keep alive to master");
}
else {
return;
Expand All @@ -457,58 +468,72 @@ public void endClientKeepAlive() {
clientKeepAlive.set(false);
}
}

public void startMasterKeepAliveThread() {

/*
* Periodically checks if the master has received
*/
public void startMasterClientPingThread() {
masterKeepAliveThread = new Thread() {
public void run() {
int secondsToSleep = 5;
while (true) {
try {
Thread.sleep(8 * 1000);
Long currTimestamp = System.currentTimeMillis() / 1000L;
Set<Client> clientSet = g.jam.getClientSet();
Set<Client> removeSet = new HashSet<Client>();
// add clients to remove set
Thread.sleep(secondsToSleep * 1000);
Set<Client> clientSet = getClientSet();
synchronized (clientSet) {
for (Client client : g.jam.getClientSet()) {
Long lastTimestamp = g.jam.keepAliveTimestampMap.get(client.getIpAddress());
System.out.println("last timestamp: " + lastTimestamp);
if (lastTimestamp < (currTimestamp - 8)) { // remove if no
System.out.println("Removing " + client.getUsername() + " from jam.");
removeSet.add(client);
}
}
// remove clients in remove set from library and clientSet
for (Client client : removeSet) {
String ipAddr = client.getIpAddress();
g.db.deleteJamSongsFromIp(ipAddr);
g.db.deleteSongsFromIp(ipAddr);
g.sendUIMessage(0);
clientSet.remove(client);
}
// tell other clients to remove music
for (final Client client : clientSet) {
for (final Client clientToRemove : removeSet) {
client.removeAllFrom(clientToRemove, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if (statusCode == 200) {
System.out.println("client " + client.getUsername() +
" removed client " + clientToRemove.getUsername() + " from jam.");
}
else {
System.out.println("client " + client.getUsername() +
" failed to remove client " + clientToRemove.getUsername() + " from jam."); }
System.out.println("Pinging clients...");
for (final Client client : getClientSet()) {
client.ping(new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if (statusCode != 200) {
removeFromJam(client);
}
});
}
}

@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
removeFromJam(client);
}
});
}
}
} catch (Exception e) {
}
catch (Exception e) {
e.printStackTrace();
}
}
}
};
masterKeepAliveThread.start();
}

/*
* Removes the specified client from the jam by removing all of its songs from
* the library and jam and sending a message to all clients telling them to
* remove its songs.
*/
private void removeFromJam(final Client clientToRemove) {
g.db.deleteJamSongsFromIp(clientToRemove.getIpAddress());
g.db.deleteSongsFromIp(clientToRemove.getIpAddress());
g.sendUIMessage(0);
synchronized (clientSet) {
clientSet.remove(clientToRemove);
for (final Client client : clientSet) {
client.removeAllFrom(clientToRemove, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if (statusCode == 200) {
System.out.println("client " + client.getUsername() +
" removed client " + clientToRemove.getUsername() + " from jam.");
}
else {
System.out.println("client " + client.getUsername() +
" failed to remove client " + clientToRemove.getUsername() + " from jam.");
}
}
});
}
}
}
}
2 changes: 1 addition & 1 deletion src/com/stanford/tutti/JoinJamActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public void handleMessage(Message msg) {
e.printStackTrace();
}

g.jam.startClientKeepAliveThread();
// g.jam.startClientKeepAliveThread();
Thread getLibraryThread = new RequestLibraryThread(g, ipAddr, PORT);
getLibraryThread.start();

Expand Down
4 changes: 2 additions & 2 deletions src/com/stanford/tutti/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ protected void onRestart() {
super.onRestart();
System.out.println("Main Activity Restarted.");
g.jam.endServerKeepAlive();
g.jam.endClientKeepAlive();
// g.jam.endClientKeepAlive();
}

@Override
Expand Down Expand Up @@ -181,7 +181,7 @@ public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if (statusCode == 200) {
System.out.println("Successfully created jam on server.");
g.jam.startServerKeepAlive(serverHostname);
g.jam.startMasterKeepAliveThread();
g.jam.startMasterClientPingThread();
g.jam.setMaster(true);
if (jamName != null && !jamName.equals("")) {
g.jam.setJamName(jamName);
Expand Down
17 changes: 17 additions & 0 deletions src/com/stanford/tutti/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Server extends NanoHTTPD {
private static final String JAM_RESTART = "/restart";
private static final String REMOVE_USER_FROM_JAM = "/removeAllFrom";
private static final String KEEP_ALIVE = "/keepAlive";
private static final String PING = "/ping";
private static final String HTTP_CLIENT_IP = "http-client-ip";
private Globals g = null;

Expand Down Expand Up @@ -133,6 +134,9 @@ else if (uri.startsWith(UPDATE_JAM)) {
else if (uri.startsWith(REMOVE_USER_FROM_JAM)) {
return removeUserFromJamResponse(parameters);
}
else if (uri.startsWith(PING)) {
return pingResponse(headers.get(HTTP_CLIENT_IP));
}
else if (uri.startsWith(KEEP_ALIVE)) {
return keepAliveResponse(headers.get(HTTP_CLIENT_IP));
}
Expand Down Expand Up @@ -460,4 +464,17 @@ private Response keepAliveResponse(String ipAddr) {
}
return new NanoHTTPD.Response("OK");
}

/*
* Returns an OK Http response if the correct master phone performs the ping and a
* bad request response if any other phone performs the ping.
*/
private Response pingResponse(String masterIpAddr) {
if (g.jam.getMasterIpAddr().equals(masterIpAddr)) {
return new NanoHTTPD.Response("OK");
}
else {
return badRequestResponse();
}
}
}

0 comments on commit 7366ce8

Please sign in to comment.