진행도(프로그레스) 처리 전송 함수 추가
parent
e813f051b0
commit
dd8ea77f4b
@ -0,0 +1,25 @@
|
||||
package cokr.xit.fims.base;
|
||||
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import cokr.xit.foundation.data.DataObject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class SseEntity {
|
||||
|
||||
private long createdAt;
|
||||
|
||||
private SseEmitter emitter;
|
||||
|
||||
private DataObject progress;
|
||||
|
||||
public SseEntity(SseEmitter emitter) {
|
||||
this.createdAt = System.currentTimeMillis();
|
||||
this.emitter = emitter;
|
||||
this.progress = new DataObject();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
package cokr.xit.fims.base.service.bean;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.catalina.connector.ClientAbortException;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cokr.xit.fims.base.SseEntity;
|
||||
import cokr.xit.foundation.component.AbstractBean;
|
||||
|
||||
@Component("sseBean")
|
||||
public class SseBean extends AbstractBean {
|
||||
private static final long ONE_HOUR = 60 * 1000;
|
||||
private String cursor;
|
||||
private ConcurrentHashMap<String, SseEntity> sseMap = new ConcurrentHashMap<>();
|
||||
private static final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||
|
||||
|
||||
@Resource(name="objectMapper")
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
/** SSE키를 등록한다.
|
||||
* @param sseKey
|
||||
* @return SseEmitter
|
||||
*/
|
||||
public SseEmitter start(String sseKey) {
|
||||
SseEmitter emitter = new SseEmitter(-1L);
|
||||
sseMap.put(sseKey, new SseEntity(emitter));
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/** 작업할 SSE키를 설정한다.
|
||||
* @param sseKey
|
||||
* @return SseBean
|
||||
*/
|
||||
public SseBean setCursor(String sseKey) {
|
||||
this.cursor = sseKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** 클라이언트에 메시지를 전송한다.
|
||||
* @param msg 메시지
|
||||
* @return SseBean
|
||||
*/
|
||||
public void send(Object msg) {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
if (se == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
se.getEmitter().send(msg);
|
||||
} catch (ClientAbortException ex) {
|
||||
if (se != null && se.getEmitter() != null) {
|
||||
se.getEmitter().complete();
|
||||
se.setEmitter(null);
|
||||
sseMap.remove(this.cursor);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (se != null && se.getEmitter() != null) {
|
||||
se.getEmitter().complete();
|
||||
se.setEmitter(null);
|
||||
sseMap.remove(this.cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 클라이언트에 종료 메시지를 전송한다.
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
public void end() {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
if (se == null) {
|
||||
return;
|
||||
}
|
||||
String msg = "FIN";
|
||||
try {
|
||||
se.getEmitter().send(msg);
|
||||
} catch (ClientAbortException ex) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (se != null && se.getEmitter() != null) {
|
||||
se.getEmitter().complete();
|
||||
se.setEmitter(null);
|
||||
sseMap.remove(this.cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Scheduled(cron = "0 0 */1 * * *")
|
||||
public void clearSseEmitter() {
|
||||
long now = System.currentTimeMillis() - ONE_HOUR;
|
||||
Iterator<String> it = sseMap.keys().asIterator();
|
||||
System.out.println("size: "+sseMap.size());
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
System.out.println("key: "+key);
|
||||
SseEntity se = sseMap.get(key);
|
||||
if (now > se.getCreatedAt()) {
|
||||
System.out.println("clear old ssemitter "+key+" : "+format.format(se.getCreatedAt()));
|
||||
if (se.getEmitter() != null) {
|
||||
se.setEmitter(null);
|
||||
}
|
||||
sseMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SseBean setProgress(String key, Object value) {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
se.getProgress().set(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SseBean increaseProgress(String key) {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
int i = se.getProgress().number(key).intValue();
|
||||
se.getProgress().set(key, i+1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public SseBean increaseProgress(String key, int num) {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
int i = se.getProgress().number(key).intValue();
|
||||
se.getProgress().set(key, i+num);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void sendProgress() {
|
||||
if(ifEmpty(this.cursor, ()->"").equals("")) {
|
||||
return;
|
||||
}
|
||||
|
||||
SseEntity se = sseMap.get(this.cursor);
|
||||
if (se == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
se.getEmitter().send(objectMapper.writeValueAsString(se.getProgress()));
|
||||
} catch (ClientAbortException ex) {
|
||||
if (se != null && se.getEmitter() != null) {
|
||||
se.getEmitter().complete();
|
||||
se.setEmitter(null);
|
||||
sseMap.remove(this.cursor);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (se != null && se.getEmitter() != null) {
|
||||
se.getEmitter().complete();
|
||||
se.setEmitter(null);
|
||||
sseMap.remove(this.cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue