package voxo.server.threads;
import java.io.IOException;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.EnumSet;
import voxo.common.entities.User;
import voxo.common.enums.EnumVerbose;
import voxo.server.Messages;
import voxo.server.actions.KickUserAction;
import voxo.server.actions.SendHeartBeat;
import voxo.server.actions.UserLogoutAction;
import voxo.server.controllers.ServerController;
import voxo.server.exceptions.RequestException;
import voxo.server.managers.UserManager;
public class HeartBeatThread implements Runnable {
private ServerController sc;
private boolean go;
private boolean beatReceived = false;
private User beatWaiting = null;
public HeartBeatThread(ServerController sc) {
this.sc = sc;
}
@Override
public void run() {
go = true;
while (go) {
ArrayList<User> alu = new ArrayList<User>();
try {
alu = UserManager.searchUserAbsolute(new User(null, null, null, null, null, true, null));
} catch (SQLException e) {
sc.getVerbose().addConsoleMsg(Messages.getString("HeartBeatThread.ERR_RetreiveUsers"), EnumSet.of(EnumVerbose.ToConsole, EnumVerbose.ToLog)); //$NON-NLS-1$
}
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(Messages.getString("HeartBeatThread.DBG_StartLoop"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
for (User u : alu) {
if (!go)
break;
beatWaiting = u;
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(String.format(Messages.getString("HeartBeatThread.DBG_BeatOnUser"), u.getUsername()), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
try {
// Send the packet
new SendHeartBeat(u.getIp());
// Wait 5 second for reply
synchronized (this) {
this.wait(5000);
}
} catch (IOException e) {} catch (InterruptedException e) {}
// Set offline
if (beatReceived == false) {
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(String.format(Messages.getString("HeartBeatThread.DBG_BeatFailedOnUser"), u.getUsername()), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
try {
new KickUserAction(u);
} catch (SQLException | IOException e) {}
try {
new UserLogoutAction(u.getIp(), u.getUsername());
} catch (IOException | SQLException | RequestException e) {}
}
// Reset State
beatReceived = false;
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(String.format(Messages.getString("HeartBeatThread.DBG_FinishedBeatOnUser"), u.getUsername()), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
}
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(Messages.getString("HeartBeatThread.DBG_LoopFinished"), EnumSet.of(EnumVerbose.ToConsole)); //$NON-NLS-1$
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
}
}
public void killHeartBeat() {
go = false;
unpause();
}
public void respondBeat(String ip) {
if (beatWaiting != null && beatWaiting.getIp().equals(ip)) {
this.beatReceived = true;
unpause();
} else {
if (sc.isDebug())
sc.getVerbose().addConsoleMsg(String.format(Messages.getString("HeartBeatThread.DBG_WrongHeart"), beatWaiting.getIp(), ip), EnumSet.of(EnumVerbose.ToConsole));
}
}
private void unpause() {
synchronized (this) {
this.notify();
}
}
}