WebSocket-无效的状态行javascript



我正在weblogic 12.1.3服务器上运行spring 3.1.2后端。为了接受websocket连接,我的配置程序如下:

public class SpringConfigurator extends Configurator {
    private static final Logger LOGGER = LoggerFactory.make();
    private static final Map<String, Map<Class<?>, String>> cache = new ConcurrentHashMap<String, Map<Class<?>, String>>();
    private static final String MAGIC_STR = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    private static final String NO_VALUE = ObjectUtils.identityToString(new Object());
    @SuppressWarnings("unchecked")
    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
        WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
        if (wac == null) {
            String message = "Failed to find the root WebApplicationContext. Was ContextLoaderListener not used?";
            LOGGER.error(message);
            throw new IllegalStateException(message);
        }
        String beanName = ClassUtils.getShortNameAsProperty(endpointClass);
        if (wac.containsBean(beanName)) {
            T endpoint = wac.getBean(beanName, endpointClass);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Using @ServerEndpoint singleton " + endpoint);
            }
            return endpoint;
        }
        Component annot = AnnotationUtils.findAnnotation(endpointClass, Component.class);
        if ((annot != null) && wac.containsBean(annot.value())) {
            T endpoint = wac.getBean(annot.value(), endpointClass);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Using @ServerEndpoint singleton " + endpoint);
            }
            return endpoint;
        }
        beanName = getBeanNameByType(wac, endpointClass);
        if (beanName != null) {
            return (T) wac.getBean(beanName);
        }
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Creating new @ServerEndpoint instance of type " + endpointClass);
        }
        return wac.getAutowireCapableBeanFactory().createBean(endpointClass);
    }
    // modifyHandshake() is called before getEndpointInstance()
    @Override
    public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
        super.modifyHandshake(sec, request, response);
    }
    private String getBeanNameByType(WebApplicationContext wac, Class<?> endpointClass) {
        String wacId = wac.getId();
        Map<Class<?>, String> beanNamesByType = cache.get(wacId);
        if (beanNamesByType == null) {
            beanNamesByType = new ConcurrentHashMap<Class<?>, String>();
            cache.put(wacId, beanNamesByType);
        }
        if (!beanNamesByType.containsKey(endpointClass)) {
            String[] names = wac.getBeanNamesForType(endpointClass);
            if (names.length == 1) {
                beanNamesByType.put(endpointClass, names[0]);
            } else {
                beanNamesByType.put(endpointClass, NO_VALUE);
                if (names.length > 1) {
                    String message = "Found multiple @ServerEndpoint's of type " + endpointClass + ", names=" + names;
                    LOGGER.error(message);
                    throw new IllegalStateException(message);
                }
            }
        }
        String beanName = beanNamesByType.get(endpointClass);
        return NO_VALUE.equals(beanName) ? null : beanName;
    }
}

问题是,当我试图通过javascript客户端打开websocket连接时,它在我调试这个位置时正确地生成了响应头:

@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
    super.modifyHandshake(sec, request, response);
}

但在客户端,它给出了以下错误:

到"ws://localhost:7001/WebSocket"的WebSocket连接失败:>WebSocket握手期间出错:状态行无效

在chrome开发工具中,响应如下:

HTTP:0.9 200 OK

我认为http请求无法升级到websocket连接。

我真的很感谢在这个问题上的任何帮助。

我今天在测试时正好遇到了这个问题http://showcase.omnifaces.org/push/socket在WebLogic 12.2.1上。

在webapp的第一次测试尝试中,WebLogic在进行websocket连接时就抛出了以下异常:

java.lang.IllegalStateException: The async-support is disabled on this request: weblogic.servlet.internal.ServletRequest
Impl@6682044b[GET /omnifaces.push/counter?e6845a3a-26ed-4520-9824-63ffd85b24eb HTTP/1.1]
    at weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:1949)
    at weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:1925)
    at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432)
    at weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilter.java:234)
    ...

事实证明,与我测试的所有其他服务器相反,WebLogic自己的TyrusServletFilter负责处理websocket握手请求,它是在通过部署的web应用程序的web.xml提供的过滤器之后内部安装的。该webapp附带了一个字符编码过滤器和一个映射在/*上的GZIP过滤器,因此它们在websocket过滤器之前被调用。乍一看,这很奇怪,但我认为这就是事实,所以我只是将<async-supported>true</async-supported>添加到那些网络应用程序提供的过滤器中,以便TyrusServletFilter可以完成它的工作。

然而,在进行websocket连接时,当发送推送消息时,客户端出现JavaScript错误,正是您面临的错误:

WebSocket连接到"ws://localhost:7001/omnifaces.push/conter"?e6845a3a-26ed-4520-9824-63ffd85b24eb'失败:WebSocket握手期间出错:状态行无效

事实证明,WebSockets就是不能处理GZIP响应。在禁用GZIP筛选器后,一切都可以完美地继续工作。

然而,根本问题是WebLogic应该在所有webapp提供的过滤器之前安装其TyrusServletFilter。我测试过的所有其他Java EE服务器都能正确地做到这一点。正如您对该问题的评论中所提到的,立即将所有websocket握手请求发送并转发到其目标URL模式的解决方法是一个很好的解决方法。另一种选择是重新配置web.xml提供的过滤器,使其不再匹配websocket握手请求,例如,使用更具体的URL模式,或者映射到特定的servlet。

相关内容

  • 没有找到相关文章

最新更新