Das habe ich bisher implementiert:
Backend (WebFlux):
Der WebFlux-Controller sendet SSE mit MediaType.TEXT_EVENT_STREAM_VALUE:
Code: Select all
@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));
}
}
}
Frontend (Angular):
Ich verwende die native EventSource-API, um SSE zu nutzen:
Code: Select all
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();
});
}
Code: Select all
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;
}
});
}
In der Entwicklung verwende ich eine Proxy-Konfiguration, um /api/events an http://localhost:8080/events:< umzuleiten br />proxy.conf.json:
Code: Select all
{
"/paypro/*": {
"target": "http://localhost:8080",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
1. In der Angular-App löst die EventSource sofort das onerror-Ereignis aus, ohne dass Daten empfangen werden.
2. Auf der Registerkarte „Netzwerk“ des Browsers wird angezeigt, dass die Anfrage an /api/events gestellt wurde, die Verbindung jedoch sofort ohne SSE-Daten geschlossen wird.
3. Es liegen keine Fehler vor Backend-Protokolle.
Was Ich habe versucht:
1. Den /events-Endpunkt mit Curl und Postman testen – funktioniert perfekt.
[img]https://i .sstatic.net/bKzCvtUr.png[/img]
2.Stellen Sie sicher, dass der Antwortheader Content-Type: text/event-stream enthält.
3. Doppelte Kontrolle die Proxy-Konfiguration in Angular.
4.Hinzufügen von CORS-Einstellungen zum WebFlux-Backend:
Java
Code: Select all
@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);
}
Irgendeine Hilfe wäre hilfreich Seien Sie sehr dankbar!