2017-01-08 7 views
1

一意のIDとIDセッションに基づいて接続するユーザーをマップする方法を知りたいので、そのIDに対して3つ以上のセッションがある場合、最初に接続したユーザーはハッシュマップから削除されます。挿入順序でHashMap値を追加および削除する方法

例:

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

ユーザーIDが既に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が複数回接続されている場合、その値はセッションごとに異なります。

つまり、基本的に私の難しさはハッシュマップをマウントすることです。どうすればいいですか?

+0

わかりません。ユーザIDはあなたのマップのキー( 'HashMap'か他の型かどうか)ですか?もしそうなら、マップの値として 'ArrayDeque 'を提案します。 'ArrayDeque'のサイズがすでに3の場合は、最初のセッションを取り出して終了し、最後に新しいセッションを追加します。 map値の型に 'Queue 'を使用するだけで、実際のインスタンスには 'ArrayDeque 'を使用することができます。 –

+0

'HashMap 'または 'HashMap 'は、あるユーザーIDから3つのセッションIDにマップできません。各キーは一度しか保持できず、そのキーの値は1つのみです。 –

答えて

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についてよく分かりませんが、私はこれをどのように行うことができるかの例を教えていただけますか?これは私の難しさです。ハッシュマップを使用して、同じUserIDに対してアクティブなセッションの数を計算します(3を超える場合は、例のように行います)。 – Florida

+1

こんにちはフロリダ、あなたの地図のキー、価値構造を提供できますか? – Sri

+0

私はマップする準備ができていませんが、値K、Vは 'String'または' int'にあります。 – Florida

1

私はあなたがユーザー/クライアントIDごとに3つのセッションIDまで保存したいことを正しく理解している場合は、私は本当に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を整数として保存しています。両方に同じタイプを使用することもできます。 KillSession()intというパラメータを指定していたので、セッションにはintを使用すると思いました。

関連する問題