缺少升级:在 netty 上同时提供 http 和 ws 4.x
missing upgrade : Serve both http and ws on netty 4.x
我正在 netty 上写一个聊天应用程序。
我尝试同时提供 HTTP
和 WS
,但 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 之后都进行更改,然后我的问题就消失了。
我正在 netty 上写一个聊天应用程序。
我尝试同时提供 HTTP
和 WS
,但 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 之后都进行更改,然后我的问题就消失了。