From e2e185ef7ffb8c3030f5e9b22830467045b67e0c Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 11 Apr 2017 01:49:43 +0300 Subject: [PATCH] Long poll listener --- pom.xml | 2 +- src/main/java/ru/dmitriymx/vkapi/VkApi.java | 2 +- .../ru/dmitriymx/vkapi/longpoll/Event.java | 19 ++++++ .../vkapi/longpoll/EventListener.java | 9 +++ .../ru/dmitriymx/vkapi/longpoll/LPRunner.java | 60 +++++++++++++++++++ .../vkapi/longpoll/LongPollListener.java | 54 +++++++++++++++++ 6 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 src/main/java/ru/dmitriymx/vkapi/longpoll/Event.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/longpoll/EventListener.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/longpoll/LPRunner.java create mode 100644 src/main/java/ru/dmitriymx/vkapi/longpoll/LongPollListener.java diff --git a/pom.xml b/pom.xml index 1923989..114a8e0 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ ru.dmitriymx vkapiuni - 1.1-SNAPSHOT + 1.2-SNAPSHOT UTF-8 diff --git a/src/main/java/ru/dmitriymx/vkapi/VkApi.java b/src/main/java/ru/dmitriymx/vkapi/VkApi.java index 20554e5..ef152ae 100644 --- a/src/main/java/ru/dmitriymx/vkapi/VkApi.java +++ b/src/main/java/ru/dmitriymx/vkapi/VkApi.java @@ -137,7 +137,7 @@ public class VkApi { } if (logger.isDebugEnabled()) { - logger.debug(response.getContent()); + logger.debug(response.getContent().trim()); } } diff --git a/src/main/java/ru/dmitriymx/vkapi/longpoll/Event.java b/src/main/java/ru/dmitriymx/vkapi/longpoll/Event.java new file mode 100644 index 0000000..f818fda --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/longpoll/Event.java @@ -0,0 +1,19 @@ +/* + * DmitriyMX + * 2017-04-11 + */ +package ru.dmitriymx.vkapi.longpoll; + +import com.google.gson.JsonArray; + +public class Event { + private JsonArray jsonArray; + + Event(JsonArray jsonArray) { + this.jsonArray = jsonArray; + } + + public JsonArray getRawData() { + return jsonArray; + } +} diff --git a/src/main/java/ru/dmitriymx/vkapi/longpoll/EventListener.java b/src/main/java/ru/dmitriymx/vkapi/longpoll/EventListener.java new file mode 100644 index 0000000..a467460 --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/longpoll/EventListener.java @@ -0,0 +1,9 @@ +/* + * DmitriyMX + * 2017-04-11 + */ +package ru.dmitriymx.vkapi.longpoll; + +public interface EventListener { + void process(Event event); +} diff --git a/src/main/java/ru/dmitriymx/vkapi/longpoll/LPRunner.java b/src/main/java/ru/dmitriymx/vkapi/longpoll/LPRunner.java new file mode 100644 index 0000000..b945f6e --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/longpoll/LPRunner.java @@ -0,0 +1,60 @@ +/* + * DmitriyMX + * 2017-04-11 + */ +package ru.dmitriymx.vkapi.longpoll; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.vkapi.VkApi; +import ru.dmitriymx.vkapi.VkApiException; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +class LPRunner implements Runnable { + private final Logger logger = LoggerFactory.getLogger(LPRunner.class); + private final VkApi vkApi; + private final String server; + private final String key; + private long ts; + Map, List> mapListeners = new HashMap<>(); + + LPRunner(VkApi vkApi, String server, String key, long ts) { + this.vkApi = vkApi; + this.server = server; + this.key = key; + this.ts = ts; + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + if (logger.isDebugEnabled()) { + logger.debug("next loop..."); + } + + try { + JsonObject jsonObject = vkApi.longExecApi( + this.server, this.key, this.ts, + 25L + ); + + JsonArray updates = jsonObject.getAsJsonArray("updates"); + if (updates.size() > 0) { + final Event event = new Event(updates); + mapListeners.getOrDefault(Event.class, Collections.emptyList()) + .forEach(listener -> listener.process(event)); + } + + this.ts = jsonObject.get("ts").getAsLong(); + } catch (VkApiException e) { + logger.error("Oops!", e); + } + } + } +} diff --git a/src/main/java/ru/dmitriymx/vkapi/longpoll/LongPollListener.java b/src/main/java/ru/dmitriymx/vkapi/longpoll/LongPollListener.java new file mode 100644 index 0000000..7b6506f --- /dev/null +++ b/src/main/java/ru/dmitriymx/vkapi/longpoll/LongPollListener.java @@ -0,0 +1,54 @@ +/* + * DmitriyMX + * 2017-04-11 + */ +package ru.dmitriymx.vkapi.longpoll; + +import com.google.gson.JsonObject; +import ru.dmitriymx.vkapi.VkApi; +import ru.dmitriymx.vkapi.VkApiException; + +import java.util.*; + +public class LongPollListener { + private Thread thread; + private LPRunner lpRunner; + + public static LongPollListener create(VkApi vkApi) throws VkApiException { + JsonObject jsonObject = vkApi.execApi("messages.getLongPollServer", + Collections.singletonMap("need_pts", "1")); + jsonObject = jsonObject.getAsJsonObject("response"); + + return new LongPollListener( + vkApi, + jsonObject.get("server").getAsString(), + jsonObject.get("key").getAsString(), + jsonObject.get("ts").getAsLong() + ); + } + + private LongPollListener(VkApi vkApi, String server, String key, long ts) { + this.lpRunner = new LPRunner(vkApi, server, key, ts); + this.thread = new Thread(this.lpRunner, "Long poll listener"); + } + + public void start() { + start(false); + } + + public void start(boolean join) { + thread.start(); + if (join) { + try { + thread.join(); + } catch (InterruptedException ignore) { + // ignore + } + } + } + + public void register(Class clazz, EventListener listener) { + List eventListeners = lpRunner.mapListeners.computeIfAbsent(clazz, list -> new ArrayList<>()); + eventListeners.add(listener); + } +}