package cn.xs.qishi.socket.standalone.queue;
import cn.xs.qishi.cache.dto.topic.StatSendMsg;
import cn.xs.qishi.socket.standalone.session.StatSocketSessionManager;
import lombok.CustomLog;
import javax.websocket.EncodeException;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 统计阻塞对了
*
* @author liuxn
* @date 2022/6/23
*/
@CustomLog
public class StatTopicHandler {
private static StatTopicHandler handler = null;
private static LinkedBlockingQueue<StatSendMsg> queue = new LinkedBlockingQueue();
private StatSocketSessionManager sessionManager;
public static StatTopicHandler getInstance() {
if (handler == null) {
handler = new StatTopicHandler();
}
return handler;
}
public void setSessionManager(StatSocketSessionManager sessionManager) {
this.sessionManager = sessionManager;
}
public StatTopicHandler() {
Thread thread = new Thread(new StatQueueThread());
thread.setName("stat_redis_topic_consumer");
thread.start();
log.info(">> 业务统计阻塞队列监听启动完毕 !!!");
}
public void put(StatSendMsg msg) {
try {
queue.put(msg);
} catch (InterruptedException e) {
log.error(">> 统计消息放入阻塞队列异常", e);
}
}
class StatQueueThread implements Runnable {
private boolean isRun = true;
@Override
public void run() {
while (isRun) {
try {
StatSendMsg msg = queue.take();
long userId = msg.getUserId();
String msgId = msg.getMsgId();
List<Session> list = sessionManager.user(userId);
int sent = 0;
log.info(">> 阻塞队列中 redis topic 消息:" + msgId);
for (Session session : list) {
try {
RemoteEndpoint.Basic basicRemote = session.getBasicRemote();
basicRemote.sendObject(msg);
String sessionId = session.getId();
log.info(">> Sent stat msg to client.sessionId:{},msgId:{},userId:{}", sessionId, msgId, userId);
sent++;
} catch (IOException | EncodeException e) {
log.error("发送消息异常", e);
if (!session.isOpen()) {
sessionManager.remove(session, userId);
}
}
}
if (sent == 0) {
log.info(">> Sent stat msg to client fail. no client userid:[{}]", userId);
}
} catch (InterruptedException e) {
log.error(">>阻塞队列 监听异常", e);
}
}
}
public void stop() {
isRun = false;
}
}
}