-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passing values from ServerEndpointConfig.Configurator to @ServerEndpoint #235
Comments
@glassfishrobot Commented |
@glassfishrobot Commented |
@glassfishrobot Commented RequestDataServerEndpointConfigurator.java public class RequestDataServerEndpointConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
Map<String, List<String>> headers = request.getHeaders();
String remoteAddr = (String) ((HttpSession) request.getHttpSession()).getAttribute("remoteAddr");
// We don't use config.getUserProperties.add because it isn't always one-to-one with a web socket connection; we use ThreadLocal instead
WebSocketRequestDataContext.setCurrentInstance(new WebSocketRequestDataContext(headers, remoteAddr));
}
} WebSocketRequestDataContext.java public class WebSocketRequestDataContext {
private final Map<String, List<String>> headers;
private final String remoteAddr;
private static final ThreadLocal<WebSocketRequestDataContext> INSTANCE
= new ThreadLocal<WebSocketRequestDataContext>() {
@Override
protected WebSocketRequestDataContext initialValue() {
return null;
}
};
public WebSocketRequestDataContext(Map<String, List<String>> headers, String remoteAddr) {
this.headers = headers;
this.remoteAddr = remoteAddr;
}
public Map<String, List<String>> getHeaders() {
return headers;
}
public String getRemoteAddr() {
return remoteAddr;
}
public static WebSocketRequestDataContext getCurrentInstance() {
return INSTANCE.get();
}
public static void setCurrentInstance(WebSocketRequestDataContext context) {
if (context == null) {
INSTANCE.remove();
} else {
INSTANCE.set(context);
}
}
} MyEndpoint.java @ServerEndpoint(value = "/myendpoint", configurator = RequestDataServerEndpointConfigurator.class)
public class MyEndpoint {
@OnOpen
public void open(Session session, EndpointConfig config) {
WebSocketRequestDataContext context = WebSocketRequestDataContext.getCurrentInstance();
if (context != null) {
Map<String, List<String>> headers = context.getHeaders();
String remoteAddr = context.getRemoteAddr();
session.getUserProperties().put("headers", headers);
session.getUserProperties().put("remoteAddr", remoteAddr);
// Prevent classloader leak
WebSocketRequestDataContext.setCurrentInstance(null);
}
}
} |
@glassfishrobot Commented |
|
is there any development on these specs? |
UserProperties being a copy or not is actually not defined in the current spec nor the TCK. Some implementations always treat User Properties as a copy per Session, others do not. I'd vote for making UserProperties a copy per Endpoint instance. |
+1 to explicitly specifying that UserProperties are per Endpoint instance / WebSocket session. |
The simplest way of having the properties per Session:
|
That approach isn't thread safe. |
As discussed in http://stackoverflow.com/questions/28939581/access-useragent-in-websocket-session/28970245 :
There is no proper way to pass information from a ServerEndpointConfig.Configurator's modifyHandshake() method to the @OnOpen/@OnMessage methods in the @serverendpoint annotated class.
Such a possibility would allow to e.g. retrieve the User-Agent HTTP header from the HandshakeRequest inside the modifyHandshake() method and then use it later on in the ServerEndpoint.
Currently in modifyHandshake() we have:
I'm not sure if the getEndpointInstance() method can be called before modifyHandshake() and the actual handshake completes so that the Session could be made available as optional parameter.
Maybe the HandshakeRequest could at least be made an optional parameter of @onopen? This would be similar to #218 and probably solve most use cases where people just want to get information about the HTTP headers.
Affected Versions
[1.1]
The text was updated successfully, but these errors were encountered: