2017-01-08 11 views
1

고유 ID와 ID 세션을 기반으로 연결하는 사용자를 매핑 할 수있는 방법을 알고 싶습니다. 그 ID에 대해 3 개 이상의 세션이있을 때 먼저 연결된 사용자가 해시 맵 등에서 제거됩니다.삽입 순서에 따라 HashMap 값을 추가 및 제거하는 방법은 무엇입니까?

예 :

UserID:3 Session:1980002 
UserID:3 Session:2841111 
UserID:3 Session:84848 

아이디에 이미 3 개 활성 세션을 포함, 가장 오래된이 제거되고 KillSession 새에 방법을 제공, 호출됩니다.

UserID:3 Session:2841111 
UserID:3 Session:84848 
UserID:3 Session:4848880 

코드 :는 User_Session가 wowza의 고유 한 세션은 각 연결에 대해 생성 된 CLIENT_ID가 데이터베이스에서 사용자의 ID입니다

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가 두 번 이상 연결되면 해당 값은 각 세션마다 다릅니다.

기본적으로 내 어려움은 해시 맵을 마운트하는 것입니다. 어떻게해야합니까?

+0

나는 이해할 수 없다. 사용자 아이디가 맵의 키 ('HashMap'이든 다른 어떤 타입이든)입니까? 그렇다면, 나는지도의 값으로'ArrayDeque '을 제안한다. 'ArrayDeque'가 이미 크기가 3이라면, 첫 번째 세션을 꺼내서 죽이고 마지막에 새로운 세션을 추가하십시오. map 값 타입으로는'Queue '을 사용할 수 있지만, 실제 인스턴스에는'ArrayDeque '를 사용하면된다. –

+0

'HashMap '또는'HashMap '는 한 사용자 ID를 세 개의 세션 ID로 매핑 할 수 없습니다. 각 키는 해당 키에 대해 단 하나의 값만 가질 수 있습니다. –

답변

2

삽입 순서대로 추가 및 제거하려면 LinkedHashMap을 사용하십시오. 난 당신이 사용자/클라이언트 ID 당 세 개의 세션 ID를 저장할 것인지 제대로 이해 한 경우

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); 
    } 
} 
+0

HashMap에 대해 많이 알지 못합니다. 어떻게 할 수 있습니까? 이것은 저의 어려움입니다. hashmap을 사용하고 동일한 UserID에 대해 얼마나 많은 세션이 활성화되었는지 계산하십시오 (3보다 큰 경우). – Florida

+1

플로리다 안녕하세요,지도의 핵심 가치 구조를 제공 할 수 있습니까? – Sri

+0

나는 매핑 할 준비가되었지만, 값 K, V는'String' 또는'int'에있을 수 있습니다. – Florida

1

(도움이 될 일의 간단한 버전), 난 정말 생각하지 않아하는 LinkedHashMap 것이다 도와주세요. HashMap과 반대로 LinkedHashMap은 삽입 순서를 유지하는 것이 맞습니다.

다른 제안이 있습니다. 별도의 일을 유지하기 위해,이 작은 보조 클래스는지도를 유지하는 것이 좋습니다 :

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 
    } 
} 

지금지도가 Queue이 삽입 순서를 유지하는 동안, 클라이언트 ID 및 세션 ID 사이의 correspondenace을 유지하는 것이다.

이렇게하면 다음과 같은 방법으로 작업을 해결할 수 있습니다. 나는지도에서 제거를 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를 정수로 저장합니다. 두 유형 모두에 동일한 유형을 사용할 수 있습니다. int 매개 변수로 KillSession()을 선언 했으므로 세션에 int을 사용한다고 생각했습니다.