Новая система сборки и избежание блокировок при отправке уведомлений #8

Merged
Royce59 merged 2 commits from dev into main 2026-02-25 17:45:40 +00:00
2 changed files with 67 additions and 28 deletions
Showing only changes of commit b7535d7664 - Show all commits

View File

@@ -2,12 +2,8 @@ FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
# Копируем готовый JAR со всеми зависимостями
COPY app.jar ./app.jar
# Копируем файл с переменными окружения
COPY .env ./.env
# Копируем файл с учётными данными для Firebase
COPY serviceAccount.json ./serviceAccount.json
# Копируем рабочую директорию
COPY . .
# Открываем порт (может быть переопределён через ENV)
EXPOSE ${PORT:-3000}

View File

@@ -3,6 +3,8 @@ package im.rosetta.service.dispatch;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
@@ -21,6 +23,7 @@ public class FirebaseDispatcher {
private UserRepository userRepository = new UserRepository();
private UserService userService = new UserService(userRepository);
private final ExecutorService executor = Executors.newFixedThreadPool(10);
public FirebaseDispatcher() {
initializeFirebase();
@@ -49,45 +52,85 @@ public class FirebaseDispatcher {
}
/**
* Отправляет push-уведомление пользователю с данным публичным ключом
* Отправляет push-уведомление пользователю с данным публичным ключом (асинхронно)
* @param publicKey публичный ключ пользователя
* @param title заголовок уведомления
* @param message текст уведомления
* @param messageText текст уведомления
*/
public void sendPushNotification(String publicKey, String title, String messageText) {
List<String> tokens = userService.getNotificationsTokens(publicKey);
if (tokens == null || tokens.isEmpty()) {
return;
}
for (String token : tokens) {
executor.submit(() -> {
try {
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle(title)
.setBody(messageText)
.build())
.setToken(token)
.build();
List<String> tokens = userService.getNotificationsTokens(publicKey);
if (tokens == null || tokens.isEmpty()) {
return;
}
String response = FirebaseMessaging.getInstance().send(message);
System.out.println("Successfully sent message: " + response);
for (String token : tokens) {
try {
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle(title)
.setBody(messageText)
.build())
.setToken(token)
.build();
FirebaseMessaging.getInstance().send(message);
} catch (Exception e) {
// Логирование ошибки
}
}
} catch (Exception e) {
System.err.println("Failed to send notification to token: " + token + ", error: " + e.getMessage());
// Логирование ошибки
}
}
});
}
/**
* Отправляет push-уведомление нескольким пользователям
* Отправляет push-уведомление нескольким пользователям (асинхронно)
* @param publicKeys список публичных ключей пользователей
* @param title заголовок уведомления
* @param messageText текст уведомления
*/
public void sendPushNotification(List<String> publicKeys, String title, String messageText) {
for (String publicKey : publicKeys) {
sendPushNotification(publicKey, title, messageText);
executor.submit(() -> {
for (String publicKey : publicKeys) {
sendPushNotificationSync(publicKey, title, messageText);
}
});
}
private void sendPushNotificationSync(String publicKey, String title, String messageText) {
try {
List<String> tokens = userService.getNotificationsTokens(publicKey);
if (tokens == null || tokens.isEmpty()) {
return;
}
for (String token : tokens) {
try {
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle(title)
.setBody(messageText)
.build())
.setToken(token)
.build();
FirebaseMessaging.getInstance().send(message);
} catch (Exception e) {
// Логирование ошибки
}
}
} catch (Exception e) {
// Логирование ошибки
}
}
/**
* Завершить работу executor при остановке приложения
*/
public void shutdown() {
executor.shutdown();
}
}