java websocket netty

netty-maven

<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.6.Final</version>
</dependency>
<dependency>
	<groupId>org.json</groupId>
	<artifactId>json</artifactId>
	<version>20150729</version>
</dependency>

<dependency>
	<groupId>commons-codec</groupId>
	<artifactId>commons-codec</artifactId>
	<version>1.10</version>
</dependency>

<!-- log4j -->
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.7.7</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.21</version>
</dependency>

Log4J

String workpath = System.getProperty("user.dir");
try {
	PropertyConfigurator.configure(new File(workpath, "log4j.properties").getCanonicalPath());
} catch (IOException e1) {
	e1.printStackTrace();
}
log4j.rootLogger=INFO,A1

# A1 is set to be a ConsoleAppender which outputs to System.out. 
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
#log4j.appender.A1.layout.ConversionPattern=%-4r %-2p [%t] [%37c] [%3x] %m%n
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%p][%t][%c] %m%n

log4j.logger.test=DEBUG

Netty-websocket

public void serverLoop() throws InterruptedException {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();

			b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) 
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						public void initChannel(SocketChannel ch) throws Exception {
							ChannelPipeline pipeline = ch.pipeline();

							pipeline.addLast(new HttpServerCodec());
							pipeline.addLast(new HttpObjectAggregator(65535));
							//这是超时逻辑 readerIdleTime 秒
							pipeline.addFirst(new IdleStateHandler(readerIdleTime, 0, 0, TimeUnit.SECONDS));

							pipeline.addLast(new WebSocketServerCompressionHandler());
							//ws://local:port/Test 一个数据包最大1M
							pipeline.addLast(new WebSocketServerProtocolHandler("/Test", null, false, 1024 * 1024));

							pipeline.addLast("handler", new WebSocketServerHandler(manager, handler));
						}
					}).option(ChannelOption.SO_BACKLOG, 128) // (5)
					.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

			f = b.bind(port).sync(); // (7)WebSocket08FrameDecoder

			System.out.println("bind "+this.port);
			f.channel().closeFuture().sync();
			System.out.println("quit");
		} finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}

Websocket数据处理

public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object> {
	//异常
	@Override  
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		logger.debug("--->exception:" + ctx.channel() + cause.getMessage());
		cause.printStackTrace();
		ctx.close();
	}
	//连接成功
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception { // (5)
		Channel channel = ctx.channel();
		logger.debug("Channel:" + channel.id() + "," + channel.remoteAddress() + ", 在线");
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		channel.attr(KEY_Base).set(new WebSocketSession());
	}
	//离线	
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
		Channel channel = ctx.channel();
		NetSession session = channel.attr(KEY_session).get();		
		logger.debug("Channel:" + channel.id() + "," + channel.remoteAddress() + "," + "掉线 ");
	}
	//超时: 需要 IdleStateHandler
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent event = (IdleStateEvent) evt;
			if (event.state() == IdleState.READER_IDLE) {
				/* 读超时 */
				logger.debug("Channel: timeout");
				ctx.channel().close();
			} else if (event.state() == IdleState.WRITER_IDLE) {

			} else if (event.state() == IdleState.ALL_IDLE) {
				/* 总超时 */
			}
		}
		super.userEventTriggered(ctx, evt);
	}
	//读取到数据
   @Override
	protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
	    //需要进行缓冲处理继续帧,未帧
		WebSocketSession webSocketSession = ctx.channel().attr(KEY_Base).get();
		if (msg instanceof TextWebSocketFrame) {
			System.out.println("收到消息:" + ((TextWebSocketFrame) msg).text());
		} else if (msg instanceof BinaryWebSocketFrame) {
			BinaryWebSocketFrame bmsg = (BinaryWebSocketFrame) msg;
			webSocketSession.appendBuf(bmsg.content());
			if (bmsg.isFinalFragment())
				channelHandleMsg(ctx, webSocketSession);
		} else if (msg instanceof ContinuationWebSocketFrame) {
			ContinuationWebSocketFrame cmsg = (ContinuationWebSocketFrame) msg;
			// logger.debug("继续帧:{}, {}", cmsg.isFinalFragment(),cmsg.content().capacity());
			webSocketSession.appendBuf(cmsg.content());
			if (cmsg.isFinalFragment())
				channelHandleMsg(ctx, webSocketSession);
		}
}

ByteBuf操作

不说

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值