介绍
最近公司年会,需要做一个弹幕功能。需要用户在手机上发送消息,然后在大屏幕上显示。
功能问题
功能还是相对简单的,主要考虑几个问题
- 多用户并发发送消息,需要一条一条显示,而不能直接刷屏
- 大屏幕消息推送问题
解决方案
第一个问题比较好解决,后端接受消息存入队列,然后开一个定时任务pop出数据就行。
第二个问题,参考这个篇文章,使用websocket实现,h5开启消息监听,后端推送消息
废话不对说,直接上代码
代码
定时任务
@Component
public class BarrageTaskServerImpl {
@Autowired
private SignService signService;
@Scheduled(cron = "0/2 * * * * ? ")//每2秒执行一次
@Override
public void pushBarrageTask() {
signService.pushBarrage();
}
服务类
@Service
public class SignServiceImpl implements SignService {
private static Logger logger = LoggerFactory.getLogger(SignServiceImpl.class);
@Autowired
private SignRedisService signRedisService;
//推送消息
@Override
public void pushBarrage() {
String barrageJson = signRedisService.popFromQueue();
if (StringUtils.isEmpty(barrageJson)) {
return;
}
BarrageMessageBo barrageMessageBo =JSONObject.parseObject(barrageJson, BarrageMessageBo.class))
//消息推送
//dubbo
logger.info(LogUtils.format("barrage_push", wsRequestVo.getMessage()));
}
//保存消息到redis
@Override
public void inBarrage(BarrageMessageBo barrageMessageBo) {
String msg=JSONObject.toJSONString(barrageMessageBo);
signRedisService.addToQueue(msg);
}
}
redis 队列
@Service
public class SignRedisServiceImpl implements SignRedisService {
@Autowired
private RedisClient redisClient;
//入队列
@Override
public void addToQueue(String content) {
String key = RushConstants.BARRAGE_KEY;
redisClient.addToList(key, false, content);
}
//出队列
@Override
public String popFromQueue() {
String key = RushConstants.BARRAGE_KEY;
return redisClient.popFromList(key);
}
}