2017-01-08 12 views
1

Я хотел бы знать, как я могу сопоставить пользователей, которые подключаются, на основе их уникального идентификатора и сеанса идентификатора, так что, если для этого идентификатора более трех сеансов, пользователи, которые подключились первым, удаляются из хэш-карты и т. Д.Как добавить и удалить значения 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 

Код:

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 является идентификатор пользователя в базе данных, User_Session уникальная сессия в Wowza генерируется для каждого соединения, эта сессия не имеют одинаковые значения, то есть, если один и тот же Client_ID подключается более одного раза, это значение будет отличаться для каждого из ваших сеансов.

То есть, в основном, моя трудность заключается в установке хэш-карты, как я могу это сделать?

+0

Я не понимаю. Является ли идентификатор пользователя ключом вашей карты (будь то «HashMap» или какой-либо другой тип)? Если это так, я предлагаю 'ArrayDeque ' как значение карты. Если 'ArrayDeque' уже имеет размер 3, выньте первый сеанс и убейте его, а затем добавьте новый сеанс в конец. Вы можете просто использовать 'Queue ' для типа значения карты, но 'ArrayDeque ' для фактических экземпляров. –

+0

«HashMap ' или 'HashMap " не может сопоставляться с одного идентификатора пользователя на три идентификатора сеанса. Он может удерживать каждую клавишу только один раз и только одно значение для этого ключа. –

ответ

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

Я мало знаю о HashMap, не могли бы вы привести пример того, как я мог это сделать? Это моя трудность, используйте hashmap и вычислите, сколько сеансов активны для одного и того же UserID, если более 3, как в примере, который я поставил. – Florida

+1

Привет, Флорида. Можете ли вы предоставить ключ, стоимость структуры вашей карты? – Sri

+0

У меня нет ничего готового для сопоставления, но значения K, V могут быть в 'String' или' int'. – Florida

1

Если я правильно понял, что вы хотите сохранить до трех идентификаторов сеансов на пользователя/идентификатор клиента, я не думаю, что будет 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 
    } 
} 

Теперь карта, что держит correspondenace между 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 
} 

Я сохраняю идентификатор клиента как строку и идентификатор сеанса как целого. Вы можете использовать один и тот же тип для обоих. Поскольку вы объявили KillSession() с параметром int, я думал, что буду использовать int для сеанса.

 Смежные вопросы

  • Нет связанных вопросов^_^