package com.qxueyou.scc.msg.service.impl;
|
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.TimeUnit;
|
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
import org.springframework.stereotype.Service;
|
|
import com.qxueyou.scc.base.model.Result;
|
import com.qxueyou.scc.base.service.ICacheService;
|
import com.qxueyou.scc.msg.model.MsgChatroomMsg;
|
import com.qxueyou.scc.msg.service.IChatroomMsgService;
|
|
@Service
|
public class ChatroomMessageBean implements IChatroomMsgService {
|
|
@Autowired
|
ICacheService redis;
|
|
private static final int PAGE_SIZE = 20;
|
|
private static final String CACHEKEY_MSG_QUEUE = "msg_chatroom_msg_"; // 实时消息队列
|
private static final String CACHEKEY_MESSAGE_A_COUNT = "msg_chatroom_message_count_"; // A类消息总数
|
private static final String CACHEKEY_MESSAGE_HISTORY = "msg_chatroom_msg_history_"; //历史消息
|
|
private static final String CACHEKEY_ONLINE_COUNT = "msg_chatroom_online_count_"; // 在线人数
|
private static final String CACHEKEY_PRAISE_COUNT = "msg_chatroom_praise_count_"; // 点赞数
|
private static final String CACHEKEY_LOTTERY_COUNT = "msg_chatroom_lottery_count_"; // 签到数
|
private static final String CACHEKEY_VIEW_COUNT = "msg_chatroom_view_count_"; // 浏览数
|
private static final String CACHEKEY_LOTTERY_RESULT_COUNT = "msg_chatroom_lottery_result_count_"; //中奖结果
|
private static final String CACHEKEY_REWARD_COUNT = "msg_chatroom_reward_count_"; //打赏次数
|
private static final String CACHEKEY_CONSULT_COUNT = "msg_chatroom_consult_count_"; //咨询次数
|
private static final String CACHEKEY_REWARD_AMOUNT = "msg_chatroom_reward_amount_"; //打赏金额
|
|
/**
|
* 发送消息
|
*/
|
|
@Override
|
public Result doSendMessage(String chatroomId, String senderId,
|
String imgPath, String alias, String content, Integer type, String userType) {
|
|
MsgChatroomMsg mes = new MsgChatroomMsg();
|
mes.setMsgId(redis.incr("ChatroomMsgId"));
|
mes.setChatroomId(chatroomId);
|
mes.setSenderId(senderId);
|
mes.setContent(content);
|
mes.setType(type);
|
mes.setAlias(alias);
|
mes.setUserType(userType);
|
mes.setImgPath(imgPath);
|
mes.setCreateTime(new Date());
|
|
//缓存消息
|
this.msgCache(chatroomId, mes);
|
this.msgTypeCountCache(chatroomId, type);
|
|
return new Result(true, null, mes);
|
|
}
|
|
/**
|
* 聊天消息剪切,
|
*
|
* @param chatroomId
|
*/
|
@Deprecated
|
private void msgListTrim(String key, String chatroomId){
|
List<MsgChatroomMsg> mesList = redis.lstRange(key, 0l, -1l);
|
if(mesList != null && !mesList.isEmpty()){
|
if(mesList.size() <= PAGE_SIZE){
|
return;
|
}
|
long index = 0;
|
long time = System.currentTimeMillis();
|
for(MsgChatroomMsg msg : mesList){
|
if(time - msg.getCreateTime().getTime()<= 10000){
|
break;
|
}
|
index ++;
|
}
|
//保留20条
|
redis.lstTrim(key, mesList.size() - index <= 20?mesList.size()-20:index, -1l);
|
}
|
}
|
|
/**
|
* 缓存消息
|
*
|
* @param chatroomId
|
* @param mes
|
*/
|
private void msgCache(String chatroomId, MsgChatroomMsg mes){
|
String key = CACHEKEY_MSG_QUEUE + chatroomId;
|
|
//先获取10秒内的数据
|
// this.msgListTrim(key, chatroomId);
|
// List<MsgChatroomMsg> mesList = redis.lstRange(key, 0l, -1l);
|
|
//获取PAGE_SIZE条以内的消息
|
List<MsgChatroomMsg> mesList= redis.lstRange(key, 0l, PAGE_SIZE);
|
|
//最近20消息过滤重复的点赞,进入,退出
|
if((MsgChatroomMsg.TYPE_PRAISE == mes.getType() || MsgChatroomMsg.TYPE_ENTER == mes.getType() || MsgChatroomMsg.TYPE_EXIT == mes.getType())
|
&& mesList.contains(mes)){
|
return;
|
}
|
redis.lstRightPush(key, mes);
|
redis.expire(key, 360, TimeUnit.DAYS);
|
}
|
|
/**
|
* 计数器
|
*
|
* @param chatroomId
|
* @param type
|
*/
|
private void msgTypeCountCache(String chatroomId, Integer type){
|
if(type == MsgChatroomMsg.TYPE_ENTER){//在线人数加一
|
redis.incr(CACHEKEY_ONLINE_COUNT + chatroomId);
|
redis.expire(CACHEKEY_ONLINE_COUNT + chatroomId, 360, TimeUnit.DAYS);
|
}
|
if(type == MsgChatroomMsg.TYPE_ENTER || type == MsgChatroomMsg.TYPE_PRAISE || type == MsgChatroomMsg.TYPE_LOTTERY
|
|| type == MsgChatroomMsg.TYPE_REWARD || type == MsgChatroomMsg.TYPE_CONSULT || type == MsgChatroomMsg.TYPE_LOTTERY_RESULT){
|
redis.incr(this.getKey(chatroomId, type));
|
redis.expire(this.getKey(chatroomId, type), 360, TimeUnit.DAYS);
|
}else if(type == MsgChatroomMsg.TYPE_EXIT){//在线人数减一
|
String key = CACHEKEY_ONLINE_COUNT + chatroomId;
|
Long value = redis.getIncrValue(key);
|
if(value.compareTo(0l)>0){
|
redis.decr(key);
|
}
|
redis.expire(key, 360, TimeUnit.DAYS);
|
}else if(type == MsgChatroomMsg.TYPE_NORMAL || type == MsgChatroomMsg.TYPE_LOTTERY_RESULT){//A类消息计数器
|
redis.incr(CACHEKEY_MESSAGE_A_COUNT + chatroomId);
|
redis.expire(CACHEKEY_MESSAGE_A_COUNT + chatroomId, 360, TimeUnit.DAYS);
|
}
|
}
|
|
//获取缓存key值
|
private String getKey(String chatroomId, Integer type){
|
String key = "";
|
switch(type){
|
case MsgChatroomMsg.TYPE_PRAISE:
|
key = CACHEKEY_PRAISE_COUNT + chatroomId;
|
break;
|
case MsgChatroomMsg.TYPE_LOTTERY:
|
key = CACHEKEY_LOTTERY_COUNT + chatroomId;
|
break;
|
case MsgChatroomMsg.TYPE_ENTER:
|
key = CACHEKEY_VIEW_COUNT + chatroomId;
|
break;
|
case MsgChatroomMsg.TYPE_REWARD:
|
key = CACHEKEY_REWARD_COUNT + chatroomId;
|
break;
|
case MsgChatroomMsg.TYPE_CONSULT:
|
key = CACHEKEY_CONSULT_COUNT + chatroomId;
|
break;
|
case MsgChatroomMsg.TYPE_LOTTERY_RESULT:
|
key = CACHEKEY_LOTTERY_RESULT_COUNT + chatroomId;
|
break;
|
default:
|
key = "";
|
}
|
return key;
|
}
|
|
/**
|
* 轮询
|
*
|
* @param chatroomId
|
* @throws Exception
|
*/
|
@Override
|
public Result latestMsg(String chatroomId) {
|
List<MsgChatroomMsg> mesList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l);
|
|
//奖金总数
|
Long rewardAmount = redis.getIncrValue(CACHEKEY_REWARD_AMOUNT + chatroomId);
|
|
Map<String, Object> data = new HashMap<String, Object>();
|
//统计数据
|
Map<String,Long> statistics = this.reStatistics(chatroomId);
|
Integer maxPage = this.getMaxPage(chatroomId, String.valueOf(statistics.get("historyMsgCount")));
|
data.put("maxPage", maxPage);
|
data.put("currentPage", maxPage);
|
data.put("onlineCount", statistics.get("onlineCount"));
|
data.put("praiseCount", statistics.get("praiseCount"));
|
data.put("viewCount", statistics.get("viewCount"));
|
data.put("lotteryCount", statistics.get("lotteryCount"));
|
data.put("rewardCount", statistics.get("rewardCount"));
|
data.put("consultCount", statistics.get("consultCount"));
|
data.put("rewardAmount", rewardAmount);
|
data.put("dataList", mesList);
|
data.put("serverTime", new Date());
|
return new Result(true, null, data);
|
}
|
|
/**
|
* 获取浏览人次
|
* @param chatroomId
|
* @throws Exception
|
*/
|
@Override
|
public Long getViewCount(String chatroomId){
|
return redis.getIncrValue(CACHEKEY_VIEW_COUNT + chatroomId);
|
}
|
|
/**
|
* 重新统计数据,读取数据库
|
*
|
* @param type
|
* @param statistics
|
* @return
|
*/
|
private Map<String,Long> reStatistics(String chatroomId){
|
Long msgCount = nul2Zero(redis.getIncrValue(CACHEKEY_MESSAGE_A_COUNT + chatroomId));
|
Long onlineCount = nul2Zero(redis.getIncrValue(CACHEKEY_ONLINE_COUNT + chatroomId));
|
Long praiseCount = nul2Zero(redis.getIncrValue(CACHEKEY_PRAISE_COUNT + chatroomId));
|
Long lotteryCount = nul2Zero(redis.getIncrValue(CACHEKEY_LOTTERY_COUNT + chatroomId));
|
Long viewCount = nul2Zero(redis.getIncrValue(CACHEKEY_VIEW_COUNT + chatroomId));
|
Long rewardCount = nul2Zero(redis.getIncrValue(CACHEKEY_REWARD_COUNT + chatroomId));
|
Long lotteryResultCount = nul2Zero(redis.getIncrValue(CACHEKEY_LOTTERY_RESULT_COUNT + chatroomId));
|
Long consultCount = nul2Zero(redis.getIncrValue(CACHEKEY_CONSULT_COUNT + chatroomId));
|
|
Map<String, Long> result = new HashMap<>();
|
result.put("msgCount", msgCount);
|
//历史消息数量,正常消息、中奖消息,打赏消息
|
result.put("historyMsgCount", msgCount+lotteryResultCount+rewardCount);
|
result.put("onlineCount", onlineCount);
|
result.put("praiseCount", praiseCount);
|
result.put("lotteryCount", lotteryCount);
|
result.put("viewCount", viewCount);
|
result.put("rewardCount", rewardCount);
|
result.put("consultCount", consultCount);
|
return result;
|
}
|
|
private Long nul2Zero(Long value) {
|
if(value==null) {
|
return 0l;
|
}
|
return value;
|
}
|
|
/**
|
* 按页获取历史消息
|
*/
|
@Override
|
public Result getHistoryMes(String chatroomId, Integer pageNo)
|
{
|
//统计数据
|
List<MsgChatroomMsg> mesList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l);
|
Map<String,Long> statistics = this.reStatistics(chatroomId);
|
Integer maxPage = getMaxPage(chatroomId, String.valueOf(statistics.get("historyMsgCount")+mesList.size()));
|
String key = CACHEKEY_MESSAGE_HISTORY + chatroomId+ "_" + pageNo;
|
if (StringUtils.isEmpty(chatroomId) || pageNo == null
|
|| pageNo > maxPage) {
|
return new Result(false, "参数错误");
|
}
|
List<MsgChatroomMsg> msgList = redis.lstAll(key);
|
msgList = this.distinct(msgList, chatroomId);
|
Map<String, Object> data = new HashMap<>();
|
data.put("currentPage", pageNo);
|
data.put("maxPage", maxPage);
|
data.put("dataList", msgList);
|
return new Result(true, null, data);
|
}
|
|
/**
|
* 去除重复消息
|
*
|
* @return
|
*/
|
private List<MsgChatroomMsg> distinct(List<MsgChatroomMsg> historyMsgList, String chatroomId){
|
List<MsgChatroomMsg> lastMsgList = redis.lstRange(CACHEKEY_MSG_QUEUE + chatroomId, 0l, -1l);
|
if(historyMsgList != null && !historyMsgList.isEmpty() && lastMsgList != null && !lastMsgList.isEmpty()){
|
for(int i=historyMsgList.size()-1;i>= 0;i--){
|
MsgChatroomMsg historyMsgChatroomMsg = historyMsgList.get(i);
|
for(MsgChatroomMsg lastMsgChatroomMsg : lastMsgList){
|
if(historyMsgChatroomMsg.getMsgId().equals(lastMsgChatroomMsg.getMsgId())){
|
historyMsgList.remove(i);
|
break;
|
}
|
}
|
}
|
}
|
return historyMsgList;
|
}
|
|
|
/**
|
* 获取A类消息最大页码
|
*
|
* @param chatroomId
|
* @return
|
*/
|
public Integer getMaxPage(String chatroomId, String msgCount) {
|
Integer count = Integer.valueOf(msgCount);
|
int maxPage = count % PAGE_SIZE == 0 ? count / PAGE_SIZE : count
|
/ PAGE_SIZE + 1;
|
return maxPage;
|
}
|
|
}
|