Results 1 to 10 of 10
  1. #1
    Power Member
    Join Date
    Sep 2013
    Location
    Coimbatore
    Posts
    121

    Light streamer delete same user loggedin previously

    In my case, I need to delete the session who logged in with the same credential in previously. It shouldn't allow keeping same user credentials to more than one user. So that I need to terminate the session if a new user logged in with same credentials. I need to serve only to the new user session.
    I have tried in my metadata like below but I couldn't disconnect the previous session of the same user name.
    private final ConcurrentHashMap<String, Map<String, String>> sessions = new ConcurrentHashMap<String, Map<String, String>>();
    private final ConcurrentHashMap<String, String> userinfo = new ConcurrentHashMap<String, String>();

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    synchronized public void notifyNewSession(String user, String sessionID, Map sessionInfo)
    throws CreditsException, NotificationException {


    assert (!sessions.containsKey(sessionID));
    sessions.put(sessionID, sessionInfo);
    if (userinfo.containsKey(user)) {
    sessions.remove(userinfo.get(user));
    System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>> REMOVED USER NAME : " + user);
    System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>> REMOVED USER SESSION : " + userinfo.get(user));
    }
    userinfo.put(user, sessionID);
    }

  2. #2
    Administrator
    Join Date
    Jul 2006
    Location
    Milan
    Posts
    1,089
    I see that you look for an existing session with the same user and, if found, you remove it from the "sessions" Map.
    But this has no effect on Lightstreamer Server as the "sessions" Map is yours.
    To have Lightstreamer Server close the previous session you should instead just throw a ConflictingSessionException, by specifying the previous session (that is, userinfo.get(user)) in its constructor.

    At this stage, you shouldn't do anything else and leave the "sessions" and "userinfo" maps unchanged.
    In practice, you will refuse the new session; but now you can expect immediately two more invocations from the Server:
    1. the notifySessionClose of the previous session;
    2. a second notifyNewSession for the new session.

    This time, you will find no sessions for the user and you will be able to accept the new session.

    For this to work, it is also important that, upon notifySessionClose, you can remove the involved user from the userInfo Map. Unfortunately, the user is not provided by the notifySessionClose invocation and it has to be inferred from the session ID.
    It's not clear to me how you manage to do that; perhaps another Map is needed.

  3. #3
    Power Member
    Join Date
    Sep 2013
    Location
    Coimbatore
    Posts
    121
    I have tried the below code, but didn't help this to solve the issue,
    if (userinfo.containsKey(user)) {
    sessions.remove(userinfo.get(user));
    notifySessionClose(userinfo.get(user));
    throw new ConflictingSessionException(-8, "Previous session termination", null, userinfo.get(user));
    } else {
    userinfo.put(user, sessionID);

    }

  4. #4
    Administrator
    Join Date
    Jul 2006
    Location
    Milan
    Posts
    1,089
    Hi, there was a misunderstanding.
    When I suggested "you should instead just throw a ConflictingSessionException" and "At this stage, you shouldn't do anything else and leave the "sessions" and "userinfo" maps unchanged" I meant something like this:

    assert (! sessions.containsKey(sessionID));
    if (userinfo.containsKey(user)) {
    throw new ConflictingSessionException(-8, "Previous session termination", null, userinfo.get(user));
    } else {
    userinfo.put(user, sessionID);
    sessions.put(sessionID, sessionInfo);
    }

    Then you should rely on the Server to call notifySessionClose and a new notifyNewSession to your Adapter.

    Also ensure that your implementation of notifySessionClose undoes exactly all that was done in notifyNewSession, which means removing the session line from both the "userinfo" and the "sessions" Map.

  5. #5
    Power Member
    Join Date
    Sep 2013
    Location
    Coimbatore
    Posts
    121
    Hi DarioCrivelli,
    I couldn't fix the issue yet, I have been trying long days but couldn't write exact code. I have written like below,
    @SuppressWarnings({ "rawtypes", "unchecked" }) @Override
    synchronized public void notifyNewSession(String user, String sessionID, Map sessionInfo)
    throws CreditsException, NotificationException, ConflictingSessionException {
    assert (!sessions.containsKey(sessionID));
    uniquelyIdentifyClient(sessionInfo);
    if (userinfo.containsKey(user) && userinfo.get(user) != sessionID) {
    String lastusessionid = userinfo.get(user);
    throw new ConflictingSessionException(-8, "Previous session termination", null, userinfo.get(user));
    } else {
    if (!userinfo.containsKey(user)) {
    userinfo.put(user, sessionID);
    }else{
    String lastusessionid = userinfo.get(user);
    Map<String, String> ssessionInfo = sessions.get(lastusessionid);
    String ua = ssessionInfo.get("USER_AGENT");
    String IP = ssessionInfo.get("REMOTE_IP");
    uaIpPairs.remove(IP + " " + ua);
    sessions.remove(lastusessionid);
    }
    sessions.put(sessionID, sessionInfo);
    }
    I added this coding if (userinfo.containsKey(user) && userinfo.get(user) != sessionID) because of refresh the page in same sesion. Please help me I couldn't understand this( you should rely on the Server to call notifySessionClose and a new notifyNewSession to your Adapter).
    And also after I used through how it will rely.

  6. #6
    Administrator
    Join Date
    Jul 2006
    Location
    Milan
    Posts
    1,089
    The code you added seems unneeded.
    The problem here is that we must agree on how the Server will invoke your Metadata Adapter.

    When I said that "you should rely on the Server to call notifySessionClose and a new notifyNewSession to your Adapter", we were talking about what happens after you throw a ConflictingSessionException. So, I mean that you should expect the Server code to behave like this:
    Code:
    try {
        String newSessionID = createRandomString();
        yourMetadataAdapter.notifyNewSession(user, newSessionId, sessionInfo);
    } catch (ConflictingSessionException e) {
        String existingSessionID = e.getConflictingSessionID();
        yourMetadataAdapter.notifySessionClose(existingSessionID);
        String differentSessionID = createRandomString();
        yourMetadataAdapter.notifyNewSession(user, differentSessionId, sessionInfo);
    }
    As you can see, if you throw a ConflictingSessionException, you will receive an invocation of notifySessionClose for the existing session to be closed and then a brand new invocation of notifyNewSession.

    Moreover, you should never expect notifyNewSession to be invoked with a session ID already used, even in case of page refresh.

    So, please stick to the original form:
    Code:
    assert (! sessions.containsKey(sessionID));
    uniquelyIdentifyClient(sessionInfo);
    if (userinfo.containsKey(user)) {
        throw new ConflictingSessionException(-8, "Previous session termination", null, userinfo.get(user));
    } else {
        userinfo.put(user, sessionID);
        sessions.put(sessionID, sessionInfo);
    }
    and focus now on notifySessionClose. How do you implement it currently?
    As I said previously, you should ensure that it undoes exactly all that was done in notifyNewSession, which means removing the session line from both the "userinfo" and the "sessions" Map.

  7. #7
    Power Member
    Join Date
    Sep 2013
    Location
    Coimbatore
    Posts
    121
    I have tried in all the way, but couldn't get the solution yet. Still the same session getting close when the page gets the refresh. The Same session also getting close. Please, could you help with some code?

  8. #8
    Administrator
    Join Date
    Jul 2006
    Location
    Milan
    Posts
    1,089
    Sorry but now I'm no longer sure I understood your goals correctly.
    If a page is handling a session S1 and gets the refresh, then the new page tries to open a second session S2.
    In this scenario, you can only manage to close S1 and let S2 succeed.
    Are you trying to achieve somenthing different?

    If you agree that S1 is the one that should be closed, then our suggestion is to keep two maps, in addition to the sessions map that you may need for your own purposes:

    Code:
        private ConcurrentHashMap<String,Map<String,String>> sessions = new ConcurrentHashMap<String,Map<String,String>>();
        private ConcurrentHashMap<String,String> userInfo = new ConcurrentHashMap<String,String>();
        private ConcurrentHashMap<String,String> sessionUser = new ConcurrentHashMap<String,String>();
    
        public void notifyNewSession(String user, String session, Map sessionInfo) throws CreditsException, NotificationException {
            assert(! sessions.containsKey(session));
            assert(! sessionUser.containsKey(session));
            if (userInfo.containsKey(user)) {
                throw new ConflictingSessionException(-8, "Previous session termination", null, userInfo.get(user));
            } else {
                sessions.put(session, sessionInfo);
                userInfo.put(user, session);
                sessionUser.put(session, user);
            }
        }
    
        public void notifySessionClose(String session) throws NotificationException {
            assert(sessions.containsKey(session));
            assert(sessionUser.containsKey(session));
            sessions.remove(session);
            String relatedUser = sessionUser.remove(session);
            userInfo.remove(relatedUser);
        }
    Then I see that your code examples involve further processing, like uniquelyIdentifyClient (which now I realize that you borrowed from our chat demo).
    Note that I dodn't include them, as I don't know your requirements on those aspects.

  9. #9
    Power Member
    Join Date
    Sep 2013
    Location
    Coimbatore
    Posts
    121
    Thanks for your reply.
    This is working for me now. When I refresh the page it didn't get terminate the currently active session. But my goal is I have to terminate if any other session opened with my credential.(User Name is unique.) If anyone opened my application by using my credential in that time If I open my browser means my session only should be active and their session should get inactive and force their page to logout. Now I think It getting terminate the existing session.(I have checked in 2 browsers by using the same credential ). But I didn't get any response from Ls while getting terminate the session. If I get the session lost message means I could force the logout the page from the client side. Is it possible getting response while terminate the session.
    I have tried in this way
    lsClient.addListener({
    onServerError: function(errorCode, errorMessage) {
    //here you can consume the error
    console.log("Connection Error: " + errorCode, errorMessage);
    }
    });

    onSubscriptionError: function(errorCode, errorMessage) {
    //here you can consume the error
    console.log(errorMessage);
    },
    onCommandSecondLevelSubscriptionError:function(err orCode,errorMessage,relatedkey) {
    //this one can only be fired in case a two-level subscription is created
    //here you can consume the error
    }
    Last edited by rvkvino; November 6th, 2017 at 01:48 PM.

  10. #10
    Administrator
    Join Date
    Jul 2006
    Location
    Milan
    Posts
    1,089
    If you refresh the page, the old page should be destroyed before it can get the session close notification;
    but if you open a new page on a different browser, the previous page is supposed to receive an invocation in onServerError, notifying error code 35.
    It is strange that you didn't see anything.

    We have to trace what happens.
    Please reproduce the case on a dedicated Server instance, by opening only the two involved pages on two different browsers.
    To keep the logs short, you should also prevent the pages from performing subscriptions, which are not relevant in this case.
    As a first step, show us the Server log, taken after setting LightstreamerLogger.push at DEBUG level.

 

 

Similar Threads

  1. Light streamer for Login user
    By in forum General
    Replies: 0
    Last Post: September 24th, 2022, 01:52 PM
  2. Light streamer user session maintenance
    By rvkvino in forum General
    Replies: 1
    Last Post: February 24th, 2017, 11:06 AM
  3. Light streamer for Login user
    By rvkvino in forum General
    Replies: 3
    Last Post: September 25th, 2013, 10:20 AM
  4. connect Light streamer and j2EE web application
    By pradeepgamage in forum Adapter SDKs
    Replies: 7
    Last Post: May 17th, 2012, 10:21 AM
  5. Replies: 5
    Last Post: September 8th, 2009, 04:07 PM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
All times are GMT +1. The time now is 05:13 AM.