gpt4 book ai didi

javascript - WebSocket - 无效的状态行javascript

转载 作者:行者123 更新时间:2023-11-29 15:31:42 27 4
gpt4 key购买 nike

我在 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 连接时,它会在我调试此位置时正确生成响应 header :

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

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

WebSocket connection to 'ws://localhost:7001/websocket' failed: Error during >WebSocket handshake: Invalid status line

在 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)
...

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

但是,在建立 websocket 连接时,客户端在发送推送消息时发生 JavaScript 错误,这正是您遇到的消息:

WebSocket connection to 'ws://localhost:7001/omnifaces.push/counter?e6845a3a-26ed-4520-9824-63ffd85b24eb' failed: Error during WebSocket handshake: Invalid status line

事实证明,WebSockets 无法处理 GZIP 响应。禁用 GZIP 过滤器后,一切继续完美运行。

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

关于javascript - WebSocket - 无效的状态行javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34297174/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com