Доступ к UserAgent в сеансе Websocket?

Используя эталонную реализацию Tyrus Java "JSR 356 - Java API для WebSocket", я не могу найти способ доступа к HTTP-соединению, которое использовалось для обновлений Websocket. Таким образом, я не могу получить доступ к заголовкам HTTP, которые отправил браузер.

Есть ли способ прочитать заголовок HTTP UserAgent?

Преобразование объекта «Session» в «TyrusSession» или подобное было бы приемлемым, я все равно должен сделать это, чтобы получить удаленный адрес. Отправка UserAgent снова в качестве сообщения внутри соединения Websocket была бы моим запасным решением.


person lathspell    schedule 09.03.2015    source источник
comment
похоже на дубликат stackoverflow.com/questions/28188172/   -  person Pavel Bucek    schedule 10.03.2015
comment
@PavelBucek: Вопрос действительно звучит похоже, но ответ не подходит: с помощью ServerEndpointConfig.Configurator я могу получить доступ только к заголовкам рукопожатия Websocket, то есть: {connection=[Upgrade], host=[localhost:8025], origin=[localhost:8025], sec-websocket-key=[vi6GPNd4GIj2oRTcwzWKYA==], sec-websocket-version=[13], upgrade=[websocket]} request.getHttpSession() работает только в контейнере Java EE и дает NULL в обычном режиме.   -  person lathspell    schedule 10.03.2015
comment
Заголовок User-Agent (при отправке) должен быть там - нет другого способа получить User-Agent (протокол веб-сокета никуда не отправляет такую ​​​​информацию).   -  person Pavel Bucek    schedule 10.03.2015
comment
О, действительно, это просто Java не отправляет. Чтобы сделать этот вопрос хоть немного полезным, я опубликую решение с исходным кодом в качестве ответа.   -  person lathspell    schedule 10.03.2015


Ответы (1)


ВНИМАНИЕ: ServerEndpointConfig является общим для всех экземпляров конечной точки, и несколько запросов на обновление могут выполняться одновременно! Смотрите комментарии!

Конечная точка получает конфигуратор:

import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/foo", configurator = MyServerEndpointConfigurator.class)
public class MyEndpoint {

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig) throws Exception {
        String ip = ((TyrusSession) session).getRemoteAddr();
        String userAgent = (String) endpointConfig.getUserProperties().get("user-agent");
        ...
   }
}

Конфигуратор выглядит так:

import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

public class MyServerEndpointConfigurator extends ServerEndpointConfig.Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        if (request.getHeaders().containsKey("user-agent")) {
            sec.getUserProperties().put("user-agent", request.getHeaders().get("user-agent").get(0)); // lower-case!
        }
    }
}
person lathspell    schedule 10.03.2015
comment
:-) это похоже на ответ, который я изначально написал, НО это не очень хорошее решение. ServerEndpointConfig является общим для всех экземпляров конечной точки, и несколько запросов на обновление могут быть выполнены одновременно, что фактически перепишет запись пользовательского агента, и конечные точки не будут иметь правильную информацию. - person Pavel Bucek; 10.03.2015
comment
Тогда мне лучше удалить свой ответ. Но я не могу найти ваше решение в другом вопросе или в примере Tyrus, который вы упомянули. В примере ServerEndpoint.Config устанавливает только некоторые заголовки ответа для клиента веб-сокета, он не передает никакой информации в ServerEndpoint, так как же мне это сделать? - person lathspell; 11.03.2015
comment
это хороший вопрос, и, к сожалению, у меня нет приемлемого ответа :-/ не могли бы вы сообщить о проблеме с WebSocket API? java.net/jira/browse/WEBSOCKET_SPEC - person Pavel Bucek; 12.03.2015