Search code examples
javaapache-flexblazeds

BlazeDS StreamingAMF: How to detect when flex client closes the connection?


I have a Flex application that connects to a BlazeDS server using the StreamingAMF channel. On the server-side the logic is handled by a custom adapter that extends ActionScriptAdapter and implements FlexSessionListener and FlexClientListener interfaces.

I am asking how can I detect which "flex-client" has closed a connection when for example the user is closing the browser? (so I can clean some infos inside the database)

I tried using the following:

1. To manually manage the command messages:

    @Override
    public Object manage(final CommandMessage commandMessage) {
        switch (commandMessage.getOperation()) {
            case CommandMessage.SUBSCRIBE_OPERATION:
                System.out.println("SUBSCRIBE_OPERATION = " + commandMessage.getHeaders());
                break;
            case CommandMessage.UNSUBSCRIBE_OPERATION:
                System.out.println("UNSUBSCRIBE_OPERATION = " + commandMessage.getHeaders());               
                break;
        }
        return super.manage(commandMessage);
    }

But the clientID's are always different from the ones that came.

2. Listening for sessionDestroyed and clientDestroyed events

    @Override
    public void clientCreated(final FlexClient client) {
        client.addClientDestroyedListener(this);
        System.out.println("clientCreated = " + client.getId());
    }

    @Override
    public void clientDestroyed(final FlexClient client) {
        System.out.println("clientDestroyed = " + client.getId());
    }

    @Override
    public void sessionCreated(final FlexSession session) {
        System.out.println("sessionCreated = " + session.getId());
        session.addSessionDestroyedListener(this);
    }

    @Override
    public void sessionDestroyed(final FlexSession session) {
        System.out.println("sessionDestroyed = " + session.getId());
    }

But those sessionDestroyed and clientDestroyed methods are never called. :(


Solution

  • I made it the following way, by using a custom adapter and a static class with a list of connected clients.

    @Override
    public Object manage(final CommandMessage commandMessage) {
        switch (commandMessage.getOperation()) {
            case CommandMessage.SUBSCRIBE_OPERATION:
                    // add user info
                    // be aware - each time the selector changes this method is called. So when you add user info check to see if you are not duplicating the clients.
                    addInfoAboutUser(commandMessage.getHeader("DSId").toString(), commandMessage.getClientId().toString());
                    break;
            case CommandMessage.UNSUBSCRIBE_OPERATION:
                    clearUserInfo(commandMessage.getClientId().toString());
                    break;
        }
        return null;
    }
    

    -

    Code INFO: addInfoAboutUser() and clearUserinfo() are private methods in my class that manage the static list of connected clients.

    -

    NOTE: when a selector is changed from the flex client side the manage() method will be called twice: 1st to unsubscribe and 2nd to subscribe with the new selector.