В чем причина «ResponseBodyEmitter уже установлен завершен» Исключение в Spring SSE - PullRequest
0 голосов
/ 25 октября 2019

У меня проблема с проектом 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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...