У меня проблема с проектом Spring, который включает события отправки сервера. Я планирую показать статус нескольких вставок MySQL в процентах. У меня есть две программы, одна из которых - веб-сервис, а другая - со слоем представления. Проблемный код находится на уровне веб-службы и вызывается со страницы, на которой отображается индикатор выполнения, показывающий, сколько процентов вставок выполнено. Проблема в том, что я получаю сообщение «IllegalStateException: ResponseBodyEmitter уже установлено завершено» в журналах tomcat. Также после получения этого исключения я не могу установить новое соединение / подписку на мой поток. Я не смог найти основную причину проблемы.
Вы видите, что в коде есть «УДАЛЕННАЯ ЧАСТЬ». Если я использую эту часть, код будет выполняться бесконечно, поэтому я получу проценты вроде «300%» и получу необходимость остановить приложение.
package com.webSocket;
import com.api.AraKontrolApi;
import com.services.PersonelService;
import com.util.SentezZamanlayici;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@RestController
public class denemeWS {
PersonelService personelService = new PersonelService();
public static int durumSayaci = 0;
private List<SseEmitter> emitters;
Thread th;
Thread Doldur;
SseEmitter sseEmitter = new SseEmitter(Long.MAX_VALUE);
int ilkGiris = 0;
@RequestMapping("/questions")
public SseEmitter questions() {
emitters = new CopyOnWriteArrayList<>();
Doldur.yield();
th.yield();
emitters.add(sseEmitter);
ilkGiris = 0;
sseEmitter.onCompletion(() -> {
emitters.remove(sseEmitter);
});
return sseEmitter;
}
@GetMapping("/tetikleyici_durumu")
public void tetikleyiciDurumuRaporla() {
/* REMOVED PART
if (emitters.size()==0) {
sseEmitter = new SseEmitter(Long.MAX_VALUE);
emitters.add(sseEmitter);
}*/
if (ilkGiris == 0) {
durumSayaci = 0;
ilkGiris = 1;
}
int allPersonelSize = personelService.getAllPersonel().size();
try {
Thread.sleep(100L);
emitters.forEach((emitter) -> {
try {
emitter.send(SseEmitter.event().name("tetikleyici").data(allPersonelSize));
emitter.send(SseEmitter.event().name("tetikleyiciAll").data(durumSayaci));
} catch (IOException ex) {
Logger.getLogger(AraKontrolApi.class.getName()).log(Level.SEVERE, null, ex);
}
});
if (durumSayaci == 0) {
Doldur = new Thread(() -> {
// Does "MySQL-Insert" increases "durumSayaci" variable that will send to client
new SentezZamanlayici().allInserts();
});
Doldur.start();
}
th = new Thread(() -> {
tetikleyiciDurumuRaporla();
});
th.start();
if (durumSayaci == allPersonelSize) {
if (th.isAlive()) {
th.yield();
Doldur.yield();
emitters.remove(sseEmitter);
}
}
} catch (InterruptedException ex) {
Logger.getLogger(denemeWS.class.getName()).log(Level.SEVERE, null, ex);
}
}
}