It appears that there is a problem in Tomcat's static UpgradeUtil.doUpgrade logic when handling concurrent connection/upgrade requests that rely on a custom ServerEndpointConfig.Configurator.modifyHandshake to grab [per-upgrade-request] client header values and inject them into the wsSession that is being created.
Specifically, the static doUpgrade does not appear to make a copy of the ServerEndpointConfig before calling modifyHandshake. As a result, any per-connection headers the Configurator may grab and put in the ServerEndpointConfig.UserProperties map will be overwritten by the last upgrade request that occurs before the upgrade logic creates the new wsSession in the WsHttpUpgradeHandler.init call. I am able to replicate this very easily by using the following server configurator code. By making concurrent websocket connect requests that place a unique "client-id" in the upgrade request headers, then grabbing that "client-id" property using the code below, ALL websocket sessions that get created will have the last "client-id" header value that came in concurrently. public class Jsr356ServerConfigurator extends ServerEndpointConfig.Configurator { @Override public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { // get the request headers - looking for security claims and endpoint ID // claims will be checked in the OnOpen call and the connection closed if AUTH check fails Map<String, List<String>> headers = request.getHeaders(); String id = headers.get("client-id").get(0); config.getUserProperties().put("client-id", id); } } @ServerEndpoint(...) Public class MyServer { @OnOpen public void onOpen(Session session) { String id = (String) session.getUserProperties().get("client-id"); _logger.warn("client ID: {}", id); } } Based on chapter 3 of the JSR-356 API document, the actual websocket handshake process defined in the websocket spec, and the online description of the process in this stackoverflow link (http://stackoverflow.com/questions/17936440/accessing-httpsession-from-httpservletrequest-in-a-web-socket-socketendpoint/17994303#17994303), it appears that we should be able to pass per-client information in the upgrade headers and we should be able to get them into the endpoint INSTANCE's Session user properties. If this is a bug, please confirm and I will create a bugzilla entry, as it is very important that that we be able to do what I've described above. If this is not a bug, can someone please describe how to obtain per-client instance data during the handshake/onOpen process? Thanks, Bob http://www.thingworx.com<http://www.thingworx.com/> Skype: bob.deremer.thingworx