2016-01-14 23:09:19 +01:00
|
|
|
package org.telegram.telegrambots.updatesreceivers;
|
2016-01-14 01:14:53 +01:00
|
|
|
|
|
|
|
import org.apache.http.HttpEntity;
|
2016-07-21 21:28:13 +02:00
|
|
|
import org.apache.http.HttpHost;
|
2016-03-16 20:11:06 +01:00
|
|
|
import org.apache.http.client.config.RequestConfig;
|
2016-05-08 01:54:53 +02:00
|
|
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
2016-01-14 01:14:53 +01:00
|
|
|
import org.apache.http.client.methods.HttpPost;
|
|
|
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
|
|
|
import org.apache.http.entity.BufferedHttpEntity;
|
|
|
|
import org.apache.http.entity.ContentType;
|
|
|
|
import org.apache.http.entity.StringEntity;
|
|
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
|
import org.apache.http.impl.client.HttpClientBuilder;
|
|
|
|
import org.apache.http.util.EntityUtils;
|
|
|
|
import org.json.JSONArray;
|
|
|
|
import org.json.JSONException;
|
|
|
|
import org.json.JSONObject;
|
2016-04-12 19:53:21 +02:00
|
|
|
import org.telegram.telegrambots.Constants;
|
2016-04-11 02:53:53 +02:00
|
|
|
import org.telegram.telegrambots.api.methods.updates.GetUpdates;
|
2016-01-14 23:09:19 +01:00
|
|
|
import org.telegram.telegrambots.api.objects.Update;
|
2016-07-21 21:28:13 +02:00
|
|
|
import org.telegram.telegrambots.bots.BotOptions;
|
2016-01-14 23:09:19 +01:00
|
|
|
import org.telegram.telegrambots.bots.ITelegramLongPollingBot;
|
2016-09-25 15:33:20 +02:00
|
|
|
import org.telegram.telegrambots.exceptions.TelegramApiRequestException;
|
2016-05-27 02:04:21 +02:00
|
|
|
import org.telegram.telegrambots.logging.BotLogger;
|
2016-01-14 01:14:53 +01:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InvalidObjectException;
|
2016-04-12 19:53:21 +02:00
|
|
|
import java.nio.charset.StandardCharsets;
|
2016-01-14 01:14:53 +01:00
|
|
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Ruben Bermudez
|
|
|
|
* @version 1.0
|
|
|
|
* @brief Thread to request updates with active wait
|
|
|
|
* @date 20 of June of 2015
|
|
|
|
*/
|
2016-04-17 15:50:54 +02:00
|
|
|
public class BotSession {
|
2016-05-01 22:43:42 +02:00
|
|
|
private static final String LOGTAG = "BOTSESSION";
|
2016-05-08 13:55:27 +02:00
|
|
|
private static final int SOCKET_TIMEOUT = 75 * 1000;
|
2016-04-11 02:53:53 +02:00
|
|
|
|
2016-01-14 23:09:19 +01:00
|
|
|
private final ITelegramLongPollingBot callback;
|
2016-01-14 01:14:53 +01:00
|
|
|
private final ReaderThread readerThread;
|
|
|
|
private final HandlerThread handlerThread;
|
2016-04-11 02:53:53 +02:00
|
|
|
private final ConcurrentLinkedDeque<Update> receivedUpdates = new ConcurrentLinkedDeque<>();
|
2016-04-12 19:53:21 +02:00
|
|
|
private final String token;
|
2016-01-14 01:14:53 +01:00
|
|
|
private int lastReceivedUpdate = 0;
|
2016-04-17 15:50:54 +02:00
|
|
|
private volatile boolean running = true;
|
|
|
|
private volatile CloseableHttpClient httpclient;
|
2016-05-08 13:55:27 +02:00
|
|
|
private volatile RequestConfig requestConfig;
|
2016-01-14 01:14:53 +01:00
|
|
|
|
2016-07-21 21:28:13 +02:00
|
|
|
public BotSession(String token, ITelegramLongPollingBot callback, BotOptions options) {
|
2016-01-14 01:14:53 +01:00
|
|
|
this.token = token;
|
|
|
|
this.callback = callback;
|
2016-05-27 02:04:21 +02:00
|
|
|
|
2016-05-08 13:55:27 +02:00
|
|
|
httpclient = HttpClientBuilder.create()
|
|
|
|
.setSSLHostnameVerifier(new NoopHostnameVerifier())
|
|
|
|
.setConnectionTimeToLive(70, TimeUnit.SECONDS)
|
|
|
|
.setMaxConnTotal(100)
|
|
|
|
.build();
|
2016-05-27 02:04:21 +02:00
|
|
|
|
2016-07-21 21:28:13 +02:00
|
|
|
RequestConfig.Builder configBuilder = RequestConfig.copy(RequestConfig.custom().build());
|
|
|
|
if (options.hasProxy()) {
|
|
|
|
configBuilder.setProxy(new HttpHost(options.getProxyHost(), options.getProxyPort()));
|
|
|
|
}
|
|
|
|
|
|
|
|
requestConfig = configBuilder.setSocketTimeout(SOCKET_TIMEOUT)
|
2016-05-08 13:55:27 +02:00
|
|
|
.setConnectTimeout(SOCKET_TIMEOUT)
|
|
|
|
.setConnectionRequestTimeout(SOCKET_TIMEOUT).build();
|
2016-05-27 02:04:21 +02:00
|
|
|
|
|
|
|
readerThread = new ReaderThread();
|
2016-04-17 15:50:54 +02:00
|
|
|
readerThread.setName(callback.getBotUsername() + " Telegram Connection");
|
2016-05-27 02:04:21 +02:00
|
|
|
readerThread.start();
|
|
|
|
|
|
|
|
handlerThread = new HandlerThread();
|
|
|
|
handlerThread.setName(callback.getBotUsername() + " Telegram Executor");
|
|
|
|
handlerThread.start();
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-05-27 02:04:21 +02:00
|
|
|
|
|
|
|
public void close() {
|
|
|
|
running = false;
|
|
|
|
if (readerThread != null) {
|
|
|
|
readerThread.interrupt();
|
|
|
|
}
|
|
|
|
if (handlerThread != null) {
|
|
|
|
handlerThread.interrupt();
|
|
|
|
}
|
|
|
|
if (httpclient != null) {
|
|
|
|
try {
|
|
|
|
httpclient.close();
|
|
|
|
httpclient = null;
|
2016-05-01 22:43:42 +02:00
|
|
|
} catch (IOException e) {
|
|
|
|
BotLogger.severe(LOGTAG, e);
|
|
|
|
}
|
2016-05-27 02:04:21 +02:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
if (callback != null) {
|
|
|
|
callback.onClosing();
|
|
|
|
}
|
2016-04-17 15:50:54 +02:00
|
|
|
}
|
2016-01-14 01:14:53 +01:00
|
|
|
|
|
|
|
private class ReaderThread extends Thread {
|
2016-04-17 15:50:54 +02:00
|
|
|
|
2016-05-27 02:04:21 +02:00
|
|
|
@Override
|
2016-01-14 01:14:53 +01:00
|
|
|
public void run() {
|
|
|
|
setPriority(Thread.MIN_PRIORITY);
|
2016-05-27 02:04:21 +02:00
|
|
|
while (running) {
|
2016-01-14 01:14:53 +01:00
|
|
|
try {
|
2016-05-08 01:54:53 +02:00
|
|
|
GetUpdates request = new GetUpdates();
|
|
|
|
request.setLimit(100);
|
2016-05-27 02:04:21 +02:00
|
|
|
request.setTimeout(Constants.GETUPDATESTIMEOUT);
|
2016-05-08 01:54:53 +02:00
|
|
|
request.setOffset(lastReceivedUpdate + 1);
|
|
|
|
String url = Constants.BASEURL + token + "/" + GetUpdates.PATH;
|
|
|
|
//http client
|
|
|
|
HttpPost httpPost = new HttpPost(url);
|
2016-04-12 19:53:21 +02:00
|
|
|
httpPost.addHeader("charset", StandardCharsets.UTF_8.name());
|
2016-03-16 20:11:06 +01:00
|
|
|
httpPost.setConfig(requestConfig);
|
2016-01-14 01:14:53 +01:00
|
|
|
httpPost.setEntity(new StringEntity(request.toJson().toString(), ContentType.APPLICATION_JSON));
|
|
|
|
|
2016-05-08 01:54:53 +02:00
|
|
|
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
|
|
|
|
HttpEntity ht = response.getEntity();
|
|
|
|
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
|
|
|
|
String responseContent = EntityUtils.toString(buf, StandardCharsets.UTF_8);
|
2016-09-25 15:33:20 +02:00
|
|
|
try {
|
|
|
|
JSONObject jsonObject = new JSONObject(responseContent);
|
|
|
|
if (!jsonObject.getBoolean(Constants.RESPONSEFIELDOK)) {
|
2016-09-29 00:44:03 +02:00
|
|
|
throw new TelegramApiRequestException("Error getting updates", jsonObject);
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
JSONArray jsonArray = jsonObject.getJSONArray(Constants.RESPONSEFIELDRESULT);
|
|
|
|
if (jsonArray.length() != 0) {
|
|
|
|
for (int i = 0; i < jsonArray.length(); i++) {
|
|
|
|
Update update = new Update(jsonArray.getJSONObject(i));
|
|
|
|
if (update.getUpdateId() > lastReceivedUpdate) {
|
|
|
|
lastReceivedUpdate = update.getUpdateId();
|
|
|
|
receivedUpdates.addFirst(update);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
synchronized (receivedUpdates) {
|
|
|
|
receivedUpdates.notifyAll();
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
} else {
|
|
|
|
synchronized (this) {
|
|
|
|
this.wait(500);
|
|
|
|
}
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
} catch (JSONException e) {
|
|
|
|
BotLogger.severe(responseContent, LOGTAG, e);
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
} catch (InvalidObjectException | TelegramApiRequestException e) {
|
2016-05-01 22:43:42 +02:00
|
|
|
BotLogger.severe(LOGTAG, e);
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
} catch (InterruptedException e) {
|
2016-10-02 22:22:24 +02:00
|
|
|
if (!running) {
|
|
|
|
receivedUpdates.clear();
|
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
BotLogger.debug(LOGTAG, e);
|
2016-05-01 22:43:42 +02:00
|
|
|
} catch (Exception global) {
|
|
|
|
BotLogger.severe(LOGTAG, global);
|
2016-04-28 09:15:11 +02:00
|
|
|
try {
|
|
|
|
synchronized (this) {
|
|
|
|
this.wait(500);
|
|
|
|
}
|
2016-05-01 22:43:42 +02:00
|
|
|
} catch (InterruptedException e) {
|
2016-10-02 22:22:24 +02:00
|
|
|
if (!running) {
|
|
|
|
receivedUpdates.clear();
|
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
BotLogger.debug(LOGTAG, e);
|
2016-04-28 09:15:11 +02:00
|
|
|
}
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
BotLogger.debug(LOGTAG, "Reader thread has being closed");
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private class HandlerThread extends Thread {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
setPriority(Thread.MIN_PRIORITY);
|
2016-05-27 02:04:21 +02:00
|
|
|
while (running) {
|
2016-01-14 01:14:53 +01:00
|
|
|
try {
|
|
|
|
Update update = receivedUpdates.pollLast();
|
|
|
|
if (update == null) {
|
|
|
|
synchronized (receivedUpdates) {
|
2016-09-25 15:33:20 +02:00
|
|
|
receivedUpdates.wait();
|
2016-01-14 01:14:53 +01:00
|
|
|
update = receivedUpdates.pollLast();
|
|
|
|
if (update == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
callback.onUpdateReceived(update);
|
2016-09-25 15:33:20 +02:00
|
|
|
} catch (InterruptedException e) {
|
|
|
|
BotLogger.debug(LOGTAG, e);
|
2016-05-01 22:43:42 +02:00
|
|
|
} catch (Exception e) {
|
|
|
|
BotLogger.severe(LOGTAG, e);
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
|
|
|
}
|
2016-09-25 15:33:20 +02:00
|
|
|
BotLogger.debug(LOGTAG, "Handler thread has being closed");
|
2016-01-14 01:14:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|