我想知道如何映射基于其唯一ID和id会话连接的用户,以便当该ID超过3个会话时,首先连接的用户将从hashmap中删除,依此类推
示例:
UserID:3 Session:1980002
UserID:3 Session:2841111
UserID:3 Session:84848
UserID已包含3个活动会话,删除最旧的会话并调用KillSession,让位给新的。
UserID:3 Session:2841111
UserID:3 Session:84848
UserID:3 Session:4848880
代码:
public void onHTTPCupertinoStreamingSessionCreate(HTTPStreamerSessionCupertino httpSession) {
String User_Session = httpSession.getSessionId();
String Client_ID = httpSession.getProperties().getPropertyStr("sql_client_id");
/* Verifies that there are already 3 active sessions and removes the oldest,
since the limit of simultaneous sessions is 3 for each user,
and add to hashmap, Client_ID and User_Session */
}
public void onHTTPCupertinoStreamingSessionDestroy(IHTTPStreamerSession httpSession) {
String User_Session = httpSession.getSessionId();
//remove from hashmap, Client_ID based on session User_Session
}
public void KillSession(int SessionId){
IApplicationInstance Instance = applicationInstance;
IHTTPStreamerSession sessions = Instance.getHTTPStreamerSessions().get(SessionId);
sessions.rejectSession();
//remove from hashmap, Client_ID based on session User_Session
}
Client_ID是数据库中用户的id,User_Session是为每个连接生成的wowza中的唯一会话,此会话没有相同的值,即,如果同一Client_ID连接多次,对于每个会话,价值都会有所不同。
也就是说,基本上我的难点是挂载hashmap,我怎么能这样做?
答案 0 :(得分:2)
如果要按插入顺序添加和删除,请使用LinkedHashMap。 (可能有帮助的简单版本)
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapExample {
static class User {
LinkedHashMap<String, Integer> sessionIds = new LinkedHashMap<>();
int userId;
public User(int userId) {
this.userId = userId;
}
public void addSession(String someField, int sessionId) {
this.sessionIds = new LinkedHashMap<String, Integer>(sessionIds) {
protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
return size() > 3;
}
};
sessionIds.put(someField, sessionId);
}
@Override
public String toString() {
return "User{" +
"sessionIds=" + sessionIds +
", userId=" + userId +
'}';
}
}
public static void main(String[] args) {
User user1 = new User(1);
user1.addSession("1980002", 1980002);
user1.addSession("84848", 84848);
user1.addSession("2841111", 2841111);
System.out.println(user1);
user1.addSession("999999", 999999);
System.out.println(user1);
user1.addSession("777777", 777777);
System.out.println(user1);
}
}
答案 1 :(得分:1)
如果我已正确理解您希望每个用户/客户端ID最多存储三个会话ID,我真的不认为LinkedHashMap
会对您有所帮助。 LinkedHashMap
维持广告订单顺序是正确的,而不是HashMap
。
我对你有不同的建议。为了保持分离,我建议这个小辅助类来保存地图:
public class MapOfSessions {
private Map<String, Queue<Integer>> sessionMap = new HashMap<>();
public int countSessions(String clientId) {
Queue<Integer> q = sessionMap.get(clientId);
if (q == null) {
return 0;
} else {
return q.size();
}
}
public int removeOldestSession(String clientId) {
return sessionMap.get(clientId).remove();
}
public void add(String clientId, int sessionId) {
Queue<Integer> q = sessionMap.get(clientId);
if (q == null) {
q = new ArrayDeque<>();
sessionMap.put(clientId, q);
}
q.add(sessionId);
}
public void remove(String clientId, int sessionId) {
sessionMap.get(clientId).remove(sessionId);
// if queue is now empty, may remove key from map
}
}
现在,地图是保持客户ID和会话ID之间的对应关系的地方,而Queue
保持了插入顺序。
通过这种方式,您可以通过以下方式解决您的任务。我已从killSession()
中删除了地图,并已将该响应权交给来电者onHTTPCupertinoStreamingSessionCreate()
。
private int maxSessionsPerUser = 3;
private MapOfSessions sessionsPerUser = new MapOfSessions();
public void onHTTPCupertinoStreamingSessionCreate(HTTPStreamerSessionCupertino httpSession) {
// use camel case for variable names: begin with lowercase, no underscores
String userSession = httpSession.getSessionId();
String clientId = httpSession.getProperties().getPropertyStr("sql_client_id");
/* Verifies that there are already 3 active sessions and removes the oldest,
since the limit of simultaneous sessions is 3 for each user,
and add to hashmap, clientId and userSession */
if (sessionsPerUser.countSessions(clientId) == maxSessionsPerUser) {
int oldestSession = sessionsPerUser.removeOldestSession(clientId);
killSession(oldestSession);
}
sessionsPerUser.add(clientId, Integer.parseInt(userSession));
}
public void onHTTPCupertinoStreamingSessionDestroy(IHTTPStreamerSession httpSession) {
String userSession = httpSession.getSessionId();
// it’s easier to remove from map when we know both clientId and userSession
String clientId = httpSession.getProperties().getPropertyStr("sql_client_id");
//remove from hashmap, clientId based on session userSession
sessionsPerUser.remove(clientId, Integer.parseInt(userSession));
}
// method name in camel case (like variable names)
public void killSession(int SessionId){
IApplicationInstance Instance = applicationInstance;
IHTTPStreamerSession sessions = Instance.getHTTPStreamerSessions().get(SessionId);
sessions.rejectSession();
//don’t remove from hashmap here, assume caller has done that
}
我将客户端ID存储为字符串,会话ID存储为整数。您可能希望对两者使用相同的类型。由于您已使用KillSession()
参数声明int
,因此我认为我会使用int
进行会话。