欢迎转载,随便转载,从这里开始复制
arctan90
业务需要实现一个web socket,没考虑Tomcat,Tomcat那个容量简直惨不忍睹,居然还有人推荐用。
基本是照着官方样例来的:
server入口
http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServer.html
服务加载的channel生成器
http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServerInitializer.html
在pipeline上加载的Handler,这个Handler用来分离http和ws,在这个样例中,请求的ws地址是ws://localhost:port/websocket
http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketIndexPageHandler.html
在这个Handler中用到一个辅助类WebSocketServerIndexPage也要加载到项目中
http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.html
另一个Handler处理websocket消息
http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketFrameHandler.html
这个Handler需要改造一下,样例只能自娱自乐,因为他在channelRead0的时候直接向ChannelHandlerContext回写
我需要一个聊天室的话,需要另外一个group,引入一个帮助类
Global.java
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
public class Global {
public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}
在context激活的时候(web socket建立完成),把channel加到group,在context注销的时候(web socket关闭) 把group从channel中移除。
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
public class WebSocketFrameHandler extends SimpleChannelInboundHandler
@Override
protected void channelRead0(ChannelHandlerContextctx, WebSocketFrameframe) throws Exception {
// TODO Auto-generated method stub
if (frameinstanceof TextWebSocketFrame) {
String request = ((TextWebSocketFrame)frame).text();
System.out.println(request);
//ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));
Global.group.writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));
} else {
String message = "unsupported frame type: " + frame.getClass().getName();
System.out.println(message);
}
}
@Override
public void channelUnregistered(ChannelHandlerContextctx) throws Exception {
Global.group.remove(ctx.channel());
}
@Override
public void channelActive(ChannelHandlerContextctx) throws Exception {
Global.group.add(ctx.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContextctx, Throwable cause)throws Exception {
// TODO Auto-generated method stub
//cause.printStackTrace();
ctx.close(); //出异常的时候关闭channel
}
}