Avoiding duplicate session detected errors in LCDS (and BlazeDS)

Original article path:http://www.alexglosband.com/?p=3

There are a number of situations where you might have more than one FlexClient in a LCDS application. For example, if you loaded two LCDS apps into a parent application as sub apps, each LCDS app would have its own FlexClient.

Note: The FlexClient represents the LCDS application on the server.

For the LCDS sub apps to work correctly they must each be able to maintain session with the server. LCDS runs in a JEE application container and leverages this container for things like security (authentication/authorization) and session handling. Currently the client application is responsible for ensuring that each FlexClient can maintain session with the server. Failing to do this will result in duplicate session detected errors like the following.

Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly.

In our example of two LCDS sub apps running in a parent application, if both sub apps load at the same time and simultaneously make requests to the server without a session already established on the server for the client application here is what happens. . . The server will receive ping requests from both sub apps. Neither ping request will have a session cookie header as there is no session cookie currently stored for the client application by the browser (or AIR runtime). The server will create a new session for each request and also create FlexClients for each request and tie these FlexClients to their respective sessions.

Note: The client ping requests will have a DSID of nil which tells the server that a new FlexClient needs to be created.

The replies for each of these requests will be returned to the client. When the browser (or other client runtime such as AIR) receives the first response it will store the session cookie set by the set cookie header.

Note: If one of the HTTP endpoints is being used, the session cookie is the standard JSESSIONID cookie used by JEE application containers. If one of the NIO HTTP endpoints is being used, this by default is the AMFSessionID cookie. The session cookie name for NIO HTTP endpoints can be changed in your services-config.xml file.

When the browser receives the second response, it will overwrite the first session cookie with the new session cookie on this response. Both session cookies have the same path element so only one will get stored by the browser. Each sub app will store the DSID (the FlexClient id) included in the reply message it received from the server.

The client is now in a bad state because on the server the first FlexClient is associated with a session that the browser no longer knows about. If the first FlexClient makes another request to the server, the request will have the session cookie header for the second FlexClient and the server will throw a duplicate session detected error. This is because it correctly believes that the FlexClient it received the request from was already associated with a different session on the server.

For the client application to make sure that FlexClients in the application don’t get into this bad state, the client application must make sure that a session is already established on the server before multiple FlexClients connect to the server at the same time. 

There are a number of ways you could implement this. If a browser is being used to run the application and not AIR, you could call a jsp page to load the application. The jsp page could both create a session for the client application and return an html wrapper to the client which would load the swf. If the application will be run in AIR as well, the parent application could call a jsp page or servlet that would create a session for the client application and then the parent application could load the sub apps. The parent application could also call a Remoting destination which would automatically create a session for the client application on the server but would also create an additional FlexClient which you may not want.

It would be nice if there was a way to resolve this in LCDS and not make application developers have to think about it. The flexibility of LCDS makes it difficult to provide a solution that works for everyone though. LCDS sub apps loaded with SWFLoader run independently of each other. To make this work LCDS would have to provide its own components for loading and managing sub apps which definitely seems like overkill. Neither JEE nor most browsers appear to provide a clean way to have more than one session per client application. For the NIO HTTP endpoints where we provide our own session implementation, it may be possible to implement a solution where the session cookie name would be unique for each FlexClient. Rather than using a common session cookie name such as AMFSESSIONID, we could possibly make the session cookie name a combination of the common name and a unique identifier such as the session id or FlexClient id which would prevent the browser from overwriting these cookies if the path element on the set cookie header was the same. For now though, you’ll have to use one of the workarounds I’ve suggested or come up with your own. Just make sure that all FlexClient instances in your application share a single session on the server.

你可能感兴趣的:(jsp,servlet,Security,UP,AIR)