使用Netty搭建WebSocket服务器

1.WebSocketServer.java

public class WebSocketServer {
private final ChannelGroup group = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); private Channel channel; public ChannelFuture start(InetSocketAddress address) {
ServerBootstrap boot = new ServerBootstrap();
boot.group(workerGroup).channel(NioServerSocketChannel.class).childHandler(createInitializer(group)); ChannelFuture f = boot.bind(address).syncUninterruptibly();
channel = f.channel();
return f;
} protected ChannelHandler createInitializer(ChannelGroup group2) {
return new ChatServerInitializer(group2);
} public void destroy() {
if (channel != null)
channel.close();
group.close();
workerGroup.shutdownGracefully();
} public static void main(String[] args) {
final WebSocketServer server = new WebSocketServer();
ChannelFuture f = server.start(new InetSocketAddress());
System.out.println("server start................");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
server.destroy();
}
});
f.channel().closeFuture().syncUninterruptibly();
} private static WebSocketServer instance; private WebSocketServer() {} public static synchronized WebSocketServer getInstance() {// 懒汉,线程安全
if (instance == null) {
instance = new WebSocketServer();
}
return instance;
} public void running(){
if(instance != null){ String port=null;
port=BusinessConfigUtils.findProperty("websocket_port");//获取端口号
if(null==port||port.length()<||!StringUtils.isNumeric(port)){
port="";
}
instance.start(new InetSocketAddress(Integer.valueOf(port)));
//ChannelFuture f =
System.out.println("----------------------------------------WEBSOCKET SERVER START----------------------------------------");
/*Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
instance.destroy();
}
});
f.channel().closeFuture().syncUninterruptibly();*/
}
}
}

2.ChatServerInitializer.java

public class ChatServerInitializer extends ChannelInitializer<Channel> {

	private final ChannelGroup group;
public ChatServerInitializer(ChannelGroup group) {
super();
this.group = group;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new HttpObjectAggregator(64*1024)); pipeline.addLast(new HttpRequestHandler("/ws")); pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); pipeline.addLast(new TextWebSocketFrameHandler(group)); } }

 3. HttpRequestHandler.java

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	private LoginTimeService loginTimeService = SpringContextHolder.getBean("loginTimeServiceImpl");
private final String wsUri; public HttpRequestHandler(String wsUri) {
super();
this.wsUri = wsUri;
} @Override
@SuppressWarnings("deprecation")
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
if (wsUri.equalsIgnoreCase(msg.getUri().substring(0, 3))) {
String userId = findUserIdByUri(msg.getUri());
if (userId != null && userId.trim() != null && userId.trim().length() > 0) {
ctx.channel().attr(AttributeKey.valueOf(ctx.channel().id().asShortText())).set(userId);// 写userid值
UserIdToWebSocketChannelShare.userIdToWebSocketChannelMap.put(userId, ctx.channel()); // 用户Id与Channel绑定
loginTimeService.onLine(userId, new Date());// 统计上线记录 } else {
}// 没有获取到用户Id
ctx.fireChannelRead(msg.setUri(wsUri).retain());
}
} private String findUserIdByUri(String uri) {// 通过Uid获取用户Id--uri中包含userId
String userId = "";
try {
userId = uri.substring(uri.indexOf("userId") + 7);
if (userId != null && userId.trim() != null && userId.trim().length() > 0) {
userId = userId.trim();
}
} catch (Exception e) {
}
return userId;
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
cause.printStackTrace(System.err);
}
}

 4. TextWebSocketFrameHandler.java

public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	private LoginTimeService loginTimeService = SpringContextHolder.getBean("loginTimeServiceImpl");
private final ChannelGroup group; public TextWebSocketFrameHandler(ChannelGroup group) {
super();
this.group = group;
} @Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
ctx.pipeline().remove(HttpRequestHandler.class);
// group.writeAndFlush("");
group.add(ctx.channel());
} else {
super.userEventTriggered(ctx, evt);
}
} @Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
group.writeAndFlush(msg.retain());
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
cause.printStackTrace();
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
Channel incoming = ctx.channel();
String userId = (String) incoming.attr(AttributeKey.valueOf(incoming.id().asShortText())).get();
UserIdToWebSocketChannelShare.userIdToWebSocketChannelMap.remove(userId);// 删除缓存的通道
loginTimeService.outLine(userId, new Date());// 下线通过
} }

  

最新文章

  1. X3850M2安装CertOS 7 KVM 2--VNC
  2. python flask应用部署
  3. ABAP WRITE、WRITE TO、FORMAT语句
  4. js和jquery获取子元素
  5. Nginx 引入线程池,提升 9 倍性能
  6. springMVC+jpa配置之简单案例
  7. 自定义 tabBar (默认 tabBar 为可读不可写类型)
  8. 02.JSP的3个编译指令
  9. 秒味课堂Angular js笔记------Angular js中的工具方法
  10. CSS display属性的值及作用
  11. ios之TableViewCell重用机制避免反复显示问题
  12. Java多线程学习笔记--生产消费者模式
  13. 【C++自我精讲】基础系列四 static
  14. 留言本,keyCode
  15. 前端性能监控:window.performance
  16. 【Luogu2458】保安站岗(动态规划)
  17. 【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
  18. Arduino—运算符
  19. EF简单的CURD操作
  20. SQL Server中多表连接时驱动顺序对性能的影响

热门文章

  1. SDUT2857:艺术联合会(简单dp)
  2. SDUT中大数实现的题目,持续更新(JAVA实现)
  3. UVA10026:Shoemaker&#39;s Problem(贪心)
  4. javascript笔记——js获取input标签中光标的索引
  5. django【F和Q】
  6. 函数对象[条款18]---《C++必知必会》
  7. Linux系统——系统安全及应用
  8. Oracle数据库创建表ID字段的自动递增
  9. Mysql 整理错误
  10. MVC 4中的前端渲染 @Helper指令