Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b719dac

Browse files
author
Tim Williscroft
committed
Changed SocketThread and GPSEndpoint to reconnect if connectivity is
lost to the GPSd TCP socket.
1 parent 045ecd6 commit b719dac

File tree

2 files changed

+80
-8
lines changed

2 files changed

+80
-8
lines changed

src/main/java/de/taimos/gpsd4java/backend/GPSdEndpoint.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ public class GPSdEndpoint {
5656

5757
private static final Logger LOG = LoggerFactory.getLogger(GPSdEndpoint.class);
5858

59-
private final Socket socket;
59+
private Socket socket;
6060

61-
private final BufferedReader in;
61+
private BufferedReader in;
6262

63-
private final BufferedWriter out;
63+
private BufferedWriter out;
6464

6565
private SocketThread listenThread;
6666

@@ -73,6 +73,12 @@ public class GPSdEndpoint {
7373
private final Object asyncWaitMutex = new Object();
7474

7575
private final AbstractResultParser resultParser;
76+
77+
private String server;
78+
79+
private int port;
80+
81+
private JSONObject watch;
7682

7783

7884
/**
@@ -87,6 +93,8 @@ public class GPSdEndpoint {
8793
* @throws IOException
8894
*/
8995
public GPSdEndpoint(final String server, final int port, final AbstractResultParser resultParser) throws UnknownHostException, IOException {
96+
this.server = server;
97+
this.port = port;
9098
if (server == null) {
9199
throw new IllegalArgumentException("server can not be null!");
92100
}
@@ -121,6 +129,7 @@ public void start() {
121129
* Stops the endpoint.
122130
*/
123131
public void stop() {
132+
124133
try {
125134
this.socket.close();
126135
} catch (final IOException e1) {
@@ -169,7 +178,7 @@ public WatchObject watch(final boolean enable, final boolean dumpData) throws IO
169178
* @throws JSONException
170179
*/
171180
public WatchObject watch(final boolean enable, final boolean dumpData, final String device) throws IOException, JSONException {
172-
final JSONObject watch = new JSONObject();
181+
watch = new JSONObject();
173182
watch.put("class", "WATCH");
174183
watch.put("enable", enable);
175184
watch.put("json", dumpData);
@@ -320,4 +329,23 @@ public void kickDevice(String path) throws IOException, JSONException {
320329
d.put("path", path);
321330
this.voidCommand("?DEVICE=" + d);
322331
}
332+
333+
/**
334+
* Our socket thread got disconnect and is exiting.
335+
*/
336+
void handleDisconnected() throws IOException{
337+
synchronized (this.asyncMutex) {
338+
socket.close();
339+
this.socket = new Socket(server, port);
340+
this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
341+
this.out = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
342+
343+
this.listenThread = new SocketThread(this.in, this, this.resultParser);
344+
this.listenThread.start();
345+
if( watch!=null){
346+
this.syncCommand("?WATCH=" + watch.toString(), WatchObject.class);
347+
}
348+
}
349+
350+
}
323351
}

src/main/java/de/taimos/gpsd4java/backend/SocketThread.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.io.BufferedReader;
2424
import java.io.IOException;
2525
import java.net.SocketException;
26-
import java.util.concurrent.atomic.AtomicBoolean;
2726

2827
import org.slf4j.Logger;
2928
import org.slf4j.LoggerFactory;
@@ -43,7 +42,7 @@ public class SocketThread extends Thread {
4342

4443
private final AbstractResultParser resultParser;
4544

46-
private final AtomicBoolean running = new AtomicBoolean(true);
45+
private final WaitableBoolean running = new WaitableBoolean(true);
4746

4847

4948
/**
@@ -86,11 +85,32 @@ public void run() {
8685
this.endpoint.handle(this.resultParser.parse(s));
8786
}
8887
} catch (final SocketException e) {
89-
// stop if socket fails
90-
break;
88+
break; // stop
9189
} catch (final Exception e) {
9290
// TODO handle this better
9391
SocketThread.LOG.warn("Problem encountered while reading/parsing/handling line", e);
92+
}
93+
}
94+
if( running.get() && !Thread.interrupted()){
95+
SocketThread.LOG.warn("Problem encountered while reading/parsing/handling line, attempting restart");
96+
retry();
97+
}
98+
}
99+
100+
101+
protected void retry(){
102+
SocketThread.LOG.debug("Disconnected from GPS socket, retrying connection");
103+
104+
while(this.running.get()){
105+
try {
106+
running.waitFor(1000);
107+
this.endpoint.handleDisconnected();
108+
SocketThread.LOG.debug("Reconnected to GPS socket");
109+
running.set(false);
110+
} catch (InterruptedException ix){
111+
break;
112+
} catch (IOException e) {
113+
SocketThread.LOG.debug("Still disconnected from GPS socket, retrying connection again");
94114
}
95115
}
96116
}
@@ -110,3 +130,27 @@ public void halt() throws InterruptedException {
110130
this.join(1000);
111131
}
112132
}
133+
/**
134+
* Not as efficient as AtomicBoolean but you can wait on it.
135+
* @author TimW
136+
*
137+
*/
138+
class WaitableBoolean {
139+
private boolean val;
140+
141+
public WaitableBoolean(boolean b) {
142+
val=b;
143+
}
144+
145+
synchronized void set(boolean value){
146+
this.val=value;
147+
notifyAll();
148+
}
149+
150+
synchronized boolean get(){
151+
return val;
152+
}
153+
synchronized public void waitFor(long millis) throws InterruptedException{
154+
super.wait(millis);
155+
}
156+
}

0 commit comments

Comments
 (0)