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()) {
开发者_如何学Go 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. :(
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.
You need to catch the event onbeforeunload and call a method on server which will cleanup all the client related data. Otherwise there is no way for the Flex client to automatically detect that it is unloaded.
The session should be destroyed when the maximum inactivity interval is exceeded...if the web.xml is properly configured.
Had the same problem as you ... solved it by a "hack" of BlazeDS ... I documented it on my confluence. Perhaps it helps with your problem: http://dev.c-ware.de/confluence/display/PUBLIC/Litening+for+BlazeDS+client+logins+and+logouts
精彩评论