WebSocket服务器返回401后浏览器无反应的原因是什么?如何解决?

WebSocket服务器返回401后浏览器无反应的原因是什么?如何解决?

Netty websocket服务器返回401,浏览器无响应的解决策略

在使用Netty构建WebSocket服务器并进行Token验证时,如果token无效,服务器返回401状态码并关闭连接,浏览器却可能无任何反应。本文分析此问题并提供解决方案。

问题描述

使用Netty开发WebSocket服务器,需要验证token。token验证失败时,服务器返回401并关闭连接,但浏览器没有响应,前端无法得知连接关闭原因。 服务器端代码示例:

private void httpResponse401(ChannelHandlerContext ctx, FullHttpRequest request) {     FullHttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.UNAUTHORIZED);     response.headers().set(HttpHeaderNames.CONTENT_LENGTH, 0);     ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);     ReferenceCountUtil.release(request); }

前端JavaScript代码:

var socket = new WebSocket("ws://127.0.0.1:18080/ws?token=xxxx");

服务器虽然返回401并关闭连接,但浏览器却没有任何反应。

解决方案

浏览器无响应是因为401响应在WebSocket握手阶段被忽略了。 我们需要在握手阶段或连接建立后进行处理。

方案一:在握手阶段返回401响应

在WebSocket握手阶段(HTTP请求阶段),token验证失败则直接返回HTTP 401响应,避免建立WebSocket连接。 修改服务器端代码:

if (!validateToken(request)) {     FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.UNAUTHORIZED);     response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=utf-8");     response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());     ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);     return; }

方案二:连接建立后发送自定义消息

如果需要在WebSocket连接建立后再处理401,可以在连接建立后立即发送自定义消息通知前端。 在Netty的WebSocketServerProtocolHandler中添加自定义处理器

channel.pipeline().addLast(new WebSocketServerProtocolHandler("/ws") {     @Override     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {         if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {             if (!validateToken()) {                 ctx.writeAndFlush(new TextWebSocketFrame("401 Unauthorized")).addListener(ChannelFutureListener.CLOSE);             }         }         super.userEventTriggered(ctx, evt);     } });

前端JavaScript代码需要监听onmessage事件

socket.onmessage = function(event) {     if (event.data === "401 Unauthorized") {         console.log("连接关闭,原因:401 Unauthorized");         socket.close();     } };

通过以上方法,浏览器就能正确处理401状态码,前端也能收到相应的反馈信息,从而解决浏览器无响应的问题。 选择哪种方案取决于具体的应用场景和需求。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享