Reputation: 531
I'm developing an app that, at startup, uses SSDP to connect to a server and retrieve it's IP Address. The SSDP class was not developed by me so I'm open to any refactoring suggestions in there as well but for this question, I'm trying to implement the logic that will keep searching for the server using SSDP while avoiding any crashes or timeout exceptions from being thrown.
Currently, my presenter class uses a private AsyncTask class to get the response from the server(called MOTA or OTA station in the commenting):
private class SearchAction extends AsyncTask<Void,Void,String>{
Context context;
SearchAction(Context context){
this.context = context;
}
protected void onPreExecute(){
view.changeVisibility(true);
}
@Override
protected String doInBackground(Void... params) {
//Get IP Address from MOTA Station
SSDP ssdp = new SSDP();
String ip = ssdp.request();
Log.d(TAG,"IP Address is: "+ ip);
return ip;
}
@TargetApi(Build.VERSION_CODES.KITKAT)
protected void onPostExecute(String ip_address){
Log.d(TAG, "IP address is: " + ip_address);
if (Objects.equals(ip_address, "")) {
view.changeVisibility(false);
// TODO: give choice to user to enter IP address manually
}else {
//otherwise go to MainActivity directly
Intent intent = new Intent(context, Main2Activity.class);
intent.putExtra("IP", ip_address);
view.navigateToMainActivity(intent);
}
}
}
The SSDP class looks like so:
public class SSDP {
public String tag = "SSDP";
//m-search string for specific OTA board
private static final String query =
"M-SEARCH * HTTP/1.1\r\n" +
"HOST: 239.255.255.250:1900\r\n"+
"MAN: \"ssdp:discover\"\r\n"+
"MX: 1\r\n"+
"ST: urn:schemas-upnp-org:device:MediaServer:1\r\n"+ // Use for OTA Board
//"ST: ssdp:all\r\n"+ // Use this for all UPnP Devices
"\r\n";
private static final int port = 1900;
//ssdp to find IP address from server
public String request(){
//response is to contain the server response in String type
//initialize send data and receive data in bytes
String response="";
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
//transfer m-search string in bytes
sendData = query.getBytes();
//wrap m-search data, multicast address and port number to the send package
DatagramPacket sendPacket = null;
try {
sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), port);
} catch (UnknownHostException e) {
Log.d(tag,"Unknown Host Exception Thrown after creating DatagramPacket to send to server");
e.printStackTrace();
}
//create socket to transport data
DatagramSocket clientSocket = null;
try {
clientSocket = new DatagramSocket();
} catch (SocketException e) {
Log.d(tag, "Socket Exception thrown when creating socket to transport data");
e.printStackTrace();
}
//send out data
try {
if (clientSocket != null) {
//time out is important
clientSocket.setSoTimeout(10000);
clientSocket.send(sendPacket);
}
} catch (IOException e) {
Log.d(tag, "IOException thrown when sending data to socket");
e.printStackTrace();
}
// receive data
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
if (clientSocket != null) {
clientSocket.receive(receivePacket);
}
} catch (IOException e) {
Log.d(tag,"IOException thrown when receiving data");
e.printStackTrace();
}
//the target package should not be empty
//try three times
for (int i =0; i<3; i++){
Log.d(tag,"Checking target package to see if its empty on iteration#: "+i);
response = new String(receivePacket.getData());
Log.d(tag,"Response contains: "+response);
if (response.contains("Location:")){
break;
}
}
String adress = "";
//filter IP address from "Location"
Matcher ma = Pattern.compile("Location: (.*)").matcher(response);
if (ma.find()){
adress+=ma.group(1);
adress = adress.split("/")[2].split(":")[0];
}
return adress;
}
}
My question is, how can I call request() repeatedly (or a specific part of request()) until I get a response from the server?
Upvotes: 0
Views: 1617
Reputation: 531
I used a Timer Task to perform the AsyncTask every 5 seconds.
private Runnable ssdpTimerTask = new Runnable() {
@Override
public void run() {
startStationSearch();
Log.d(TAG,"Running SSDP search - iteration: "+ssdpIteration);
ssdpIteration++;
mHandler.postDelayed(ssdpTimerTask,5000);
}
};
Upvotes: 1