From 5e56a1fbf80033cf5cc30ec7767d3cd92ab41cde Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 17 Nov 2015 13:46:03 +1300 Subject: Update device status via async web service --- src/org/traccar/database/ConnectionManager.java | 28 ++++++++++------- src/org/traccar/web/AsyncServlet.java | 40 ++++++++++++++++++------- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index cb7b4b6d8..345bb4577 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -36,13 +36,13 @@ public class ConnectionManager { private final Map activeDevices = new HashMap<>(); private final Map positions = new HashMap<>(); - private final Map> listeners = new HashMap<>(); + private final Map> listeners = new HashMap<>(); public ConnectionManager(DataManager dataManager) { if (dataManager != null) { try { for (Position position : dataManager.getLatestPositions()) { - this.positions.put(position.getDeviceId(), position); + positions.put(position.getDeviceId(), position); } } catch (SQLException error) { Log.warning(error); @@ -79,14 +79,19 @@ public class ConnectionManager { Log.warning(error); } - // TODO call listener + if (listeners.containsKey(deviceId)) { + for (UpdateListener listener : listeners.get(deviceId)) { + listener.onUpdateDevice(device); + } + } } public synchronized void updatePosition(Position position) { long deviceId = position.getDeviceId(); positions.put(deviceId, position); + if (listeners.containsKey(deviceId)) { - for (DataCacheListener listener : listeners.get(deviceId)) { + for (UpdateListener listener : listeners.get(deviceId)) { listener.onUpdatePosition(position); } } @@ -109,32 +114,33 @@ public class ConnectionManager { return result; } - public interface DataCacheListener { + public interface UpdateListener { + void onUpdateDevice(Device device); void onUpdatePosition(Position position); } - public void addListener(Collection devices, DataCacheListener listener) { + public void addListener(Collection devices, UpdateListener listener) { for (long deviceId : devices) { addListener(deviceId, listener); } } - public synchronized void addListener(long deviceId, DataCacheListener listener) { + public synchronized void addListener(long deviceId, UpdateListener listener) { if (!listeners.containsKey(deviceId)) { - listeners.put(deviceId, new HashSet()); + listeners.put(deviceId, new HashSet()); } listeners.get(deviceId).add(listener); } - public void removeListener(Collection devices, DataCacheListener listener) { + public void removeListener(Collection devices, UpdateListener listener) { for (long deviceId : devices) { removeListener(deviceId, listener); } } - public synchronized void removeListener(long deviceId, DataCacheListener listener) { + public synchronized void removeListener(long deviceId, UpdateListener listener) { if (!listeners.containsKey(deviceId)) { - listeners.put(deviceId, new HashSet()); + listeners.put(deviceId, new HashSet()); } listeners.get(deviceId).remove(listener); } diff --git a/src/org/traccar/web/AsyncServlet.java b/src/org/traccar/web/AsyncServlet.java index ddcbce2ff..c55fd6e75 100644 --- a/src/org/traccar/web/AsyncServlet.java +++ b/src/org/traccar/web/AsyncServlet.java @@ -36,6 +36,7 @@ import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.database.ConnectionManager; import org.traccar.helper.Log; +import org.traccar.model.Device; import org.traccar.model.Position; public class AsyncServlet extends BaseServlet { @@ -60,7 +61,8 @@ public class AsyncServlet extends BaseServlet { private final Set devices = new HashSet<>(); private Timeout sessionTimeout; private Timeout requestTimeout; - private final Map positions = new HashMap<>(); + private final Set deviceUpdates = new HashSet<>(); + private final Set positionUpdates = new HashSet<>(); private AsyncContext activeContext; private void logEvent(String message) { @@ -76,7 +78,7 @@ public class AsyncServlet extends BaseServlet { Collection initialPositions = Context.getConnectionManager().getInitialState(devices); for (Position position : initialPositions) { - positions.put(position.getDeviceId(), position); + positionUpdates.add(position); } Context.getConnectionManager().addListener(devices, dataListener); @@ -86,17 +88,34 @@ public class AsyncServlet extends BaseServlet { return devices.contains(deviceId); } - private final ConnectionManager.DataCacheListener dataListener = new ConnectionManager.DataCacheListener() { + private final ConnectionManager.UpdateListener dataListener = new ConnectionManager.UpdateListener() { + @Override + public void onUpdateDevice(Device device) { + synchronized (AsyncSession.this) { + logEvent("onUpdateDevice deviceId: " + device.getId()); + if (!destroyed) { + if (requestTimeout != null) { + requestTimeout.cancel(); + requestTimeout = null; + } + deviceUpdates.add(device); + if (activeContext != null) { + response(); + } + } + } + } + @Override public void onUpdatePosition(Position position) { synchronized (AsyncSession.this) { - logEvent("onUpdate deviceId: " + position.getDeviceId()); + logEvent("onUpdatePosition deviceId: " + position.getDeviceId()); if (!destroyed) { if (requestTimeout != null) { requestTimeout.cancel(); requestTimeout = null; } - positions.put(position.getDeviceId(), position); + positionUpdates.add(position); if (activeContext != null) { response(); } @@ -142,7 +161,7 @@ public class AsyncServlet extends BaseServlet { sessionTimeout = null; } - if (!positions.isEmpty()) { + if (!deviceUpdates.isEmpty() || !positionUpdates.isEmpty()) { response(); } else { requestTimeout = GlobalTimer.getTimer().newTimeout( @@ -160,15 +179,16 @@ public class AsyncServlet extends BaseServlet { result.add("success", true); if (Context.getConfig().getBoolean("web.oldAsyncFormat")) { - result.add("data", JsonConverter.arrayToJson(positions.values())); + result.add("data", JsonConverter.arrayToJson(positionUpdates)); } else { JsonObjectBuilder data = Json.createObjectBuilder(); - data.add("devices", Json.createArrayBuilder().build()); // TODO: send device status - data.add("positions", JsonConverter.arrayToJson(positions.values())); + data.add("devices", JsonConverter.arrayToJson(deviceUpdates)); + data.add("positions", JsonConverter.arrayToJson(positionUpdates)); result.add("data", data.build()); } - positions.clear(); + deviceUpdates.clear(); + positionUpdates.clear(); try { response.getWriter().println(result.build().toString()); -- cgit v1.2.3