각2 스프링 부트 서버 사이드 이벤트
누가 나에게 봄 부트 서버 부대 행사에 대한 예를 들어줄 수 있습니까?
기본적으로 서버 사이드 이벤트를 브라우저로 푸시해야 합니다.앵귤러 2와 스프링부츠 백엔드를 사용하고 있습니다.좋은 예시를 못 찾겠으니 예시를 하나만 제시해주세요.
@Controller
public class SSEController {
private final List<SseEmitter> emitters = new ArrayList<>();
@RequestMapping(path = "/stream", method = RequestMethod.GET)
public SseEmitter stream() throws IOException {
SseEmitter emitter = new SseEmitter();
emitters.add(emitter);
emitter.onCompletion(() -> emitters.remove(emitter));
return emitter;
}
}
서버에서 데이터를 지속적으로 푸시하는 방법과 Angular 2에서 이 이벤트를 구독하는 방법은 무엇입니까?
스프링 레스트 컨트롤러가 있습니다.
SseController.java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@RestController
public class SSEController {
public static final List<SseEmitter> emitters = Collections.synchronizedList( new ArrayList<>());
@RequestMapping(path = "/stream", method = RequestMethod.GET)
public SseEmitter stream() throws IOException {
SseEmitter emitter = new SseEmitter();
emitters.add(emitter);
emitter.onCompletion(() -> emitters.remove(emitter));
return emitter;
}
}
ServiceClass.java
public void sendSseEventsToUI(Notification notification) { //your model class
List<SseEmitter> sseEmitterListToRemove = new ArrayList<>();
SSEController.emitters.forEach((SseEmitter emitter) -> {
try {
emitter.send(notification, MediaType.APPLICATION_JSON);
} catch (IOException e) {
emitter.complete();
sseEmitterListToRemove.add(emitter);
e.printStackTrace();
}
});
SSEController.emitters.removeAll(sseEmitterListToRemove);
}
마지막으로 Angular2 구성 요소에서 이 작업을 수행합니다.
알림.구성요소.ts
import {Component, OnInit} from '@angular/core';
declare let EventSource:any;
@Component({
selector: 'notification-cmp',
templateUrl: 'notification.component.html'
})
export class NotificationComponent implements OnInit {
connect(): void {
let source = new EventSource('http://localhost:8080/stream');
source.addEventListener('message', message => {
let n: Notification; //need to have this Notification model class in angular2
n = JSON.parse(message.data);
console.log(message.data);
});
}
}
프라탑 A로부터의 답.K는 대단합니다.하지만 좀 더 깨끗하게 유지하려면 인터페이스를 구현하는 Notification 서비스를 만들어야 합니다.다음과 같은 경우:
알림 서비스Impl.java
public class NotificationServiceImpl implements NotificationService {
public static final List<SseEmitter> emitters = Collections.synchronizedList(new ArrayList<>());
@Override
public SseEmitter initSseEmitters() {
SseEmitter emitter = new SseEmitter();
emitters.add(emitter);
emitter.onCompletion(() -> emitters.remove(emitter));
return emitter;
}
@Override
public void sendSseEventsToUI(WebSource notification) {
List<SseEmitter> sseEmitterListToRemove = new ArrayList<>();
this.emitters.forEach((SseEmitter emitter) -> {
try {
emitter.send(notification, MediaType.APPLICATION_JSON);
} catch (IOException e) {
emitter.complete();
sseEmitterListToRemove.add(emitter);
e.printStackTrace();
}
});
this.emitters.removeAll(sseEmitterListToRemove);
}
}
Notification Service.java
public interface NotificationService {
public SseEmitter initSseEmitters();
public void sendSseEventsToUI(WebSource notification);
}
SSEController.java
@RestController
@RequestMapping("/mystream")
public class SSEController {
@Autowired
NotificationServiceImpl INotificationServiceImpl;
@CrossOrigin
@RequestMapping(path = "/streamsource", method = RequestMethod.GET)
public SseEmitter stream() throws IOException {
return INotificationServiceImpl.initSseEmitters();
}
}
위의 답변이 큰 도움이 되었습니다.
그리고..
실제 데이터 푸시를 수신하려면..
코드는 다음과 같습니다.
source.onmessage = (message)=>{
let n:Notification = JSON.parse(message.data);
}
source.addEventListener('message', message => {
// There is no data property available on 'message' here
let n: Notification;
n = JSON.parse(message.data);
console.log(message.data);
});
이제 Spring Webflux를 사용하면 다음과 같은 MediaType만 사용하면 작업을 더 쉽게 수행할 수 있습니다.
@GetMapping(value = "/queue/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<EventNotification> streamEvents() {
return managerService.streamEvents();
}
따라서 다음과 같은 아키텍처를 만들 수 있습니다.
RSocket 예제를 사용하여 https://github.com/htenjo/vqueue 에서 작동 중인 구현을 확인할 수 있습니다.
언급URL : https://stackoverflow.com/questions/40987560/angular-2-spring-boot-server-side-events
'bestsource' 카테고리의 다른 글
열 이름의 공백 제거 또는 바꾸기 (0) | 2023.09.11 |
---|---|
memcpy 0바이트를 상수 변수로 - 정의되지 않은 동작? (0) | 2023.09.11 |
@ControllerAdvice로 간단한 서블릿 필터 작동 (0) | 2023.09.11 |
열 모드에서 flexbox 항목을 랩할 때 컨테이너의 너비가 증가하지 않습니다. (0) | 2023.09.11 |
여러 데이터 프레임 열을 기준으로 주파수 카운트 가져오기 (0) | 2023.09.11 |