일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- flask
- 생명주기 콜백
- DI
- bean
- cookie
- JWT
- python
- javascript
- real time web
- server send event
- Spring Security
- Java
- Stream
- spring
- Anolog
- WIL
- Hibernate
- html
- oauth
- session
- jenkins
- jQuery
- 항해99
- web
- Project
- google oauth
- programmers
- JPA
- hanghae99
- SseEmitter
Archives
- Today
- Total
끄적끄적 코딩일지
[Spring] SSeEitter 사용하기 본문
SSE(Server Send Event)에 대한 개념은 아래글을 참고하자
SSE는 Http 기반의 Streaming을 활용한 기술이므로 Spring-web 라이브러리가 필요하다.
SSE를 사용하여 데이터 베이스 데이터를 실시간으로 받아오도록 해 보자
Step 1. Controller에서 SSE 만들기
@Controller
public class SseController{
// Client의 현제 연결 목록
private Set<SseEmitter> emitterSet = new CopyOnWriteArraySet<>();
@Autowired
private MemberService service;
// 새로운 Sse 만들기
@GetMapping("/createSse")
public SseEmitter createEmmit(){
SseEmitter emit = new SseEmitter(60*60*1000L); // 입력값은 time out 시간(ms)이다.
//emitterSet에 만든 연결을 추가한다.
emitterSet.add(emitter);
// timeout이 발생하거나 완료되면 연결 목록에서 제거한다.
emitter.onTimeout(()->emitterSet.remove(emitter));
emitter.onCompletion(()->emitterSet.remove(emitter));
return emitter;
}
// Member정보 추가 API
@PostMapping("/member")
@ResponseBody
public Member saveMember(@RequestBody Member member){
return service.save(member);
}
// Member 정보 수정 API
@PatchMapping("/member")
@ResponseBody
public Member saveMember(@RequestBody Member member){
return service.save(member);
}
// 비동기처리
// 이벤트 감지
// 이벤트로 Member 객체가 입력되면 해당 이벤트 리스너에서 처리한다.
@Async
@EventListener
public void catchEvent(Member member){
// 전송 오류가 나면 연결이 끊긴 Sse으로 간주하고 목록에서 제거한다.
List<SseEmitter> deadEmit= new ArrayList<>();
emitterSet.forEach(e->{
try{
// sse라는 이름의 이벤트로 Member객체를 JSON타입으로 전송한다.
e.send(SseEmitter.event().name("sse").data(member,MediaType.APPLICATION_JSON));
}catch (Exception ex){
deadEmit.add(e);
}
});
emitterSet.removeAll(deadEmit);
}
}
Step 2. Service 만들기
위에서 member가 service.save를 통해 database에 생성될때 Member을 Event으로 등록해주어야 한다.
@Service
@RequiredArgsConstructor
@Getter
public class MemberService {
// JpaRepository를 상속한 Member Repository
private final MemberRepo repo;
// Spring에서 Event를 발생시켜주는 Bean
// Spring 실행할때 기본적으로 bean으로 등록하기때문에 따로 만들지 않아도 된다.
private final ApplicationEventPublisher eventPublisher;
public Member save(Member member){
// database에 member 저장
Member m = repo.save(member);
// ApplicationEventPublisher에 저장한 Member를 이벤트으로 발생
eventPublisher.publishEvent(m);
return m;
}
}
Step 3. JavaScript상에서 SSE 연결하기
// 입력한 Url으로 Sse를 만들고 이벤트를 기다린다.
const eventSource = new EventSource('/createSse');
// addEventListener으로 이벤트 처리하기
eventSource.addEventListener("sse",(event)=>{
// "sse"라는 이벤트 발생시 처리 로직
// 이번 예제에서는 테이블에 새로운 row를 추가하거나 수정을 하도록 함
console.log(event);
// data으로 설정한 값 받기
const data = JSON.parse(event.data);
let trs = document.getElementById(data.id);
if(trs === null){
trs = document.getElementById('origin').cloneNode(true);
trs.setAttribute("id",data.id);
trs.style.display="";
document.getElementsByTagName('tbody')[0].append(trs);
trs.getElementsByClassName("idx")[0].innerText= document.getElementsByTagName('tbody')[0].children.length-1;
}
trs.getElementsByClassName("member-email")[0].innerText=data.email;
trs.getElementsByClassName("member-name")[0].innerText=data.name;
trs.getElementsByClassName("member-profile")[0].setAttribute("src",data.picture);
})
실행 결과
'Spring' 카테고리의 다른 글
[Spring] Jenkins를 사용해 자동배포 구현하기 (1) (0) | 2022.07.16 |
---|---|
[Spring] Spring, React 연동하기(CORS,Proxy) (0) | 2022.06.12 |
[Spring] Entity에서 Collection 사용하기 (0) | 2022.06.09 |
[Spring] Spring Security + OAuth2 (2) - 코드 구현하기 (0) | 2022.06.08 |
[Spring] Spring Security + OAuth2 (1) - 프로젝트 설정하기 (0) | 2022.06.08 |