Вот что я реализовал на данный момент:
Бэкэнд (WebFlux):
Контроллер WebFlux отправляет SSE с использованием MediaType.TEXT_EVENT_STREAM_VALUE:
Код: Выделить всё
@GetMapping(value = "/purchasedItems",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
@ResponseStatus(HttpStatus.ACCEPTED)
public Flux
findAllPurchasedItem(ServerHttpResponse response){
response.getHeaders().add("Cache-Control", "no-cache, no-transform");
response.getHeaders().add("Connection", "keep-alive");
return purchaseService.getPurchasedItems()
.doOnNext(item -> System.out.println("Sending item: " + item.getName()))
.doOnError(error -> System.out.println("Error sending items: "+ error.getMessage()))
.doFinally(signalType -> System.out.println("Streaming finished: " + signalType));
}
}
}
Фронтенд (Angular):
Я использую собственный API EventSource для использования SSE:
Код: Выделить всё
private apiUrl = 'http://localhost:8080/paypro/purchasedItems';
fetchPurchasedItems(): Observable {
return new Observable(observer => {
const eventSource = new EventSource(this.apiUrl);
eventSource.onmessage = (event) => {
try {
debugger;
const data = JSON.parse(event.data);
console.log('Received SSE data:', data); // Debugging line
observer.next(data);
} catch (error) {
console.error('Error parsing SSE data:', event.data, error);
observer.error(error);
}
};
eventSource.addEventListener('message', (evt) => {
console.log('Received SSE data:', evt.data); // Debugging line
observer.next(evt);
});
eventSource.onerror = (error) => {
console.error('EventSource error:', error);
debugger;
observer.error(error);
eventSource.close();
};
return () => eventSource.close();
});
}
Код: Выделить всё
public loadData() {
// this.purchasedItems$ = this.service.fetchPurchasedItems();
this.isLoading = true;
this.service.fetchPurchasedItems().subscribe({
next: (data) => {
console.log('Fetched data:', data);
debugger;
this.purchasedItems=[...this.purchasedItems,...data];
this.cd.detectChanges(); // Trigger change detection
},
error: (err) => {
console.error('Error fetching data', err);
this.isLoading = false;
}
});
}
В разработке я использую конфигурацию прокси для перенаправления /api/events на http://localhost:8080/events:proxy.conf.json:
Код: Выделить всё
{
"/paypro/*": {
"target": "http://localhost:8080",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
1. В приложении Angular EventSource немедленно запускает событие onerror без получения данных.
2.На вкладке «Сеть» браузера показано, что запрос к /api/events выполнен, но соединение немедленно закрывается без каких-либо данных SSE.
3.Ошибок в сети нет. серверные журналы.
Что я пробовал:
1. Тестирование конечной точки /events с помощью Curl и Postman — работает отлично.

2. Убедитесь, что заголовок ответа включает Content-Type: text/event-stream.
3.Двойная проверка конфигурации прокси-сервера в Angular.
4.Добавление настроек CORS в бэкэнд WebFlux:
java
Код: Выделить всё
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:4200");
config.addAllowedMethod("*");
config.addAllowedHeader("*");
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
Любая помощь будем очень признательны!
Подробнее здесь: https://stackoverflow.com/questions/793 ... bflux-back