最近路演项目已经到了上线阶段,现在来梳理下路演开发中所遇到的问题。
首先是直播间实时在线人数问题
当时的考虑是用阿里的在线人数接口,然后通过解析阿里的数据获得当前房间里的在线人数。由于阿里的数据有5min的延迟,导致用户刚进入直播间,头像已经显示了,但是阿里给返回的人数为0,故将此方案排除。
最后确定的方案是通过websocket去实现实时在线人数,代码如下:
@Component
@Slf4j
@ServerEndpoint(value = "/websocket/{channelId}")
public class WebsocketService {
//记录当前连接,每个客户端都有对应的session,服务器端通过它向客户端发送消息
private Session session;
private String channelId;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
private static final Map<Session,String> map = new ConcurrentHashMap<>();
/**
* @description 有新的链接建立成功时调用该方法
* @param session
* @return void
**/
@OnOpen
public void open(Session session, @PathParam(value="channelId")String channelId) throws IOException {
List<String> list = new ArrayList<>();
this.session = session;
map.put(session,channelId);
for (String str : map.values()){
if(channelId.equals(str)){
list.add(channelId);
}
}
sendMessage(channelId,list.size());
log.info("当前在线用户:" + map.size());
}
@OnClose
public void onClose(Session session) throws IOException {
this.session = session;
String channelId = map.get(session);
int count = subOnlineNum(session);
sendMessage(channelId,count);
log.info("当前在线用户:" + count);
}
public void sendMessage(String channelId,int count) throws IOException {
List<Session> sessions = new ArrayList<>();
for(Session key: map.keySet()){
if(map.get(key).equals(channelId)){
sessions.add(key);
}
}
for (Session session : sessions){
session.getBasicRemote().sendText(String.valueOf(count));
}
}
/**
* @description 在线数减1
* @param
* @return void
**/
public static synchronized int subOnlineNum(Session session){
String channelId = map.get(session);
List<String> list = new ArrayList<>();
for (String str : map.values()){
if(channelId.equals(str)){
list.add(channelId);
}
}
map.remove(session);
return list.size()-1;
}当不同的房间号有链接进来,就向当前所在房间的所有用户发送当前的在线人数,已解决实时在线人数问题。
还有一种方案是咨询做过直播的前辈,他给的方案使用心跳机制去解决实时在线人数,因为当时项目没有申请redis资源,所以这种方案没没经过验算,故只提供个思路。
创建完直播间,直接写一个redis 的key .用set 去维护,每个直播间单独一个key
如果直播间 关播 直接把key 清了就结束了,但是web 端维不了退房的操作。这里可能需要把key 设计成 hash。
里面放心跳时间。 k:uid v:heartTime,服务器邀请定时把没有心跳的用户清出去。
hash 里面用户在,切心跳正常 说明还在看直播,如果定时任务清理的话 ,只需要判断,用户在hash 里面就行
如果还有其它方案的话,可以留言大家进行沟通。
在路演项目的上线阶段,遇到了直播间实时在线人数的挑战。首先考虑使用阿里在线人数接口,但由于5min延迟问题,该方案被排除。最终选择了通过WebSocket实现实时更新,在用户加入或离开时向所有用户广播当前在线人数。另外,还提及了一种心跳机制的方案,利用Redis维护在线状态,但因未申请Redis资源未实际验证。欢迎分享更多解决方案。
729





