缺少升级:在 netty 上同时提供 http 和 ws 4.x

missing upgrade : Serve both http and ws on netty 4.x

我正在 netty 上写一个聊天应用程序。

我尝试同时提供 HTTPWS,但 http 响应只有这些消息

not a WebSocket handshake request: missing upgrade

这是我的代码片段。

InitChannel 方法

p.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast( new LoggingHandler(LogLevel.INFO))
.addLast(new WebSocketServerProtocolHandler("/chat"),
        new WsUserAcceptHandler(), new WsChatServerHandler())
.addLast(new HttpStaticFileHandler("/", ChatServer.index))
.addLast(new HttpNotFoundHandler());

而在channelRead上,WsUserAcceptHandler、WsChatHandler都只处理TextWebSocketFrame,其他都是ctx.fireChannelRead(msg)

WsUserAcceptHandler

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("WsUserAcceptHandler#channelRead :" + msg.getClass());
        if (msg instanceof TextWebSocketFrame) {
            TextWebSocketFrame tMsg = (TextWebSocketFrame) msg;
            ChatMessage chatMsg = ChatMessage.parse(tMsg.text());

            if (chatMsg.getCommand().equals("CONN")) {


                SqlSession sqlSession = SqlSessionFactoryManager
                        .getSqlSession();
                User u = new User();
                ChatRoom roomInfo = new ChatRoom();

                try {
                    u.setUserSessionkey(chatMsg.getSessionKey());
                    UserMapper userMapper = sqlSession
                            .getMapper(UserMapper.class);
                    u = userMapper.get(u);

                    ChatInfoMapper chatInfoMapper = sqlSession
                            .getMapper(ChatInfoMapper.class);
                    roomInfo = chatInfoMapper.getRoomInfo(chatMsg.getRoomNo());

                } catch (Exception e) {

                } finally {
                    sqlSession.close();
                }

                if (u != null) {
                    System.out.println("userInfo");
                    System.out.println(u.toString());

                    AttrKeys attrs = AttrKeys.getInstance();

                    ctx.channel().attr(attrs.sessionKey())
                            .set(u.getUserSessionkey());
                    ctx.channel().attr(attrs.userInfo()).set(u);
                    currClients.registerUserChannelGroup(
                            String.valueOf(chatMsg.getRoomNo()), ctx.channel());

                    ChatDataMapper cdm = new ChatDataMapper();
                    List<ChatMessage> latests = cdm.gets(chatMsg.getRoomNo(), 20);

                    HashMap<String, Object> map = new HashMap<String, Object>();
                    map.put("recentMessages", latests);
                    map.put("roomInfo", roomInfo);

                    JsonResultSet<HashMap<String, Object>> res = new JsonResultSet<HashMap<String, Object>>();
                    res.setResultCode("S0000");
                    res.setResultMessage("Success");
                    res.setCommand(chatMsg.getCommand());
                    res.setResult(map);
                    System.out.println(res.toJsonString());

                    TextWebSocketFrame outputMsg = new TextWebSocketFrame(
                            res.toJsonString());
                    ctx.writeAndFlush(outputMsg);
                } else {
                    ctx.flush();
                }

                // ctx.writeAndFlush(outputMsg);
            } else if (chatMsg.getCommand().equals("DISCONN")) {
                ctx.channel().attr(sessionKeyAttr).get();
                currClients.unregisterUserChannelGroup(
                        String.valueOf(chatMsg.getRoomNo()), ctx.channel());

                ctx.fireChannelInactive();
            }
        }

        ctx.fireChannelRead(msg); // if not instance of TextWebsocketFrame
    }

WsChatServerHandler

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        System.out.println("WsChatServerHandler##channelRead :" + msg.getClass());
        if(msg instanceof TextWebSocketFrame){
            ChatMessage chatMsg = ChatMessage.parse(((TextWebSocketFrame) msg).text());
//          chatMsg.setC_user_nm(ctx.channel().attr(sessionKeyAttr).get()  );
            if(chatMsg.getCommand().equals("TEXT")){
                ChannelGroup roomUsers = currClients.getUserChannelGroup(String.valueOf(chatMsg.getRoomNo ()));

                AttrKeys attrs = AttrKeys.getInstance();
                User u = ctx.channel().attr(attrs.userInfo()).get();


                JsonResultSet<ChatMessage> res = new JsonResultSet<ChatMessage>();
                res.setResultCode("S0000");
                res.setResultMessage("Success");
                res.setCommand(chatMsg.getCommand());

                chatMsg.setSessionKey(null);
                chatMsg.setCommand(null);

                chatMsg.setSeq(ChatServer.nextChatDataSeq());
                chatMsg.setUserSeq(u.getUserSeq());
                chatMsg.setUserNm(u.getUserNm());
                chatMsg.setUserType(u.getUserType());
                chatMsg.setUserThumb(StaticVar.default_img_url+u.getUserThumb()+"&imgMode=origin");
                chatMsg.setUserPic(StaticVar.default_img_url+u.getUserPic()+"&imgMode=thumb");

                ChatDataMapper mapper = new ChatDataMapper();
                mapper.put(chatMsg);

                System.out.println(chatMsg.toString());

                res.setResult(chatMsg);

                TextWebSocketFrame outputMsg = new TextWebSocketFrame(res.toJsonString());

                sendPush(chatMsg, String.valueOf(chatMsg.getRoomNo()));
//              gcmTest(chatMsg);

                roomUsers.writeAndFlush(outputMsg);
            } else if(chatMsg.getCommand().equals("MORE")){

            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }

我解决了。是Netty版本问题

我在 Netty 4.1.0.CR6 之前使用过,然后我尝试在版本和 4.0.0 之后都进行更改,然后我的问题就消失了。