Netty入门(一)-3.x User Guide

一、简单的DiscardServer

1.当然,首先要引入Netty 3.x的jar包

2.最简单的官方用户指引文档的例子:DiscardServer

  • DiscardServerHandler.java
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

public class DiscardServerHandler extends SimpleChannelHandler {
	/**
	 * DiscardServerHandler extends SimpleChannelHandler, which is an
	 * implementation of ChannelHandler. SimpleChannelHandler provides various
	 * event handler methods that you can override. For now, it is just enough
	 * to extend SimpleChannelHandler rather than to implement the handler
	 * interfaces by yourself.
	 * 
	 */

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		/**
		 * 
		 We override the messageReceived event handler method here. This
		 * method is called with a MessageEvent, which contains the received
		 * data, whenever new data is received from a client. In this example,
		 * we ignore the received data by doing nothing to implement the DISCARD
		 * protocol.
		 */

		/**
		 * 
		 It is safe to assume the message type in socket transports is always
		 * ChannelBuffer. ChannelBuffer is a fundamental data structure which
		 * stores a sequence of bytes in Netty. It's similar to NIO ByteBuffer,
		 * but it is easier to use and more flexible. For example, Netty allows
		 * you to create a composite ChannelBuffer which combines multiple
		 * ChannelBuffers reducing the number of unnecessary memory copy.
		 */

		ChannelBuffer buf = (ChannelBuffer) e.getMessage();
		while (buf.readable()) {
			System.out.println((char) buf.readByte());
			System.out.flush();
		}

	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
			throws Exception {
		/**
		 * 
		 exceptionCaught event handler method is called with an ExceptionEvent
		 * when an exception was raised by Netty due to I/O error or by a
		 * handler implementation due to the exception thrown while processing
		 * events. In most cases, the caught exception should be logged and its
		 * associated channel should be closed here, although the implementation
		 * of this method can be different depending on what you want to do to
		 * deal with an exceptional situation. For example, you might want to
		 * send a response message with an error code before closing the
		 * connection.
		 */
		Channel ch = e.getChannel();
		ch.close();

	}

}
  • DiscardServer.java
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

public class DiscardServer {
	public static void main(String[] args) throws Exception {
		/**
		 * 
		 * ChannelFactory is a factory which creates and manages Channels and
		 * its related resources. It processes all I/O requests and performs I/O
		 * to generate ChannelEvents. Netty provides various ChannelFactory
		 * implementations. We are implementing a server-side application in
		 * this example, and therefore NioServerSocketChannelFactory was used.
		 * Another thing to note is that it does not create I/O threads by
		 * itself. It is supposed to acquire threads from the thread pool you
		 * specified in the constructor, and it gives you more control over how
		 * threads should be managed in the environment where your application
		 * runs, such as an application server with a security manager.
		 */
		ChannelFactory factory = new NioServerSocketChannelFactory(
				Executors.newCachedThreadPool(),
				Executors.newCachedThreadPool());
		/**
		 * ServerBootstrap is a helper class that sets up a server. You can set
		 * up the server using a Channel directly. However, please note that
		 * this is a tedious process and you do not need to do that in most
		 * cases.
		 */
		ServerBootstrap bootstrap = new ServerBootstrap(factory);
		/**
		 * Here, we configure the ChannelPipelineFactory. Whenever a new
		 * connection is accepted by the server, a new ChannelPipeline will be
		 * created by the specified ChannelPipelineFactory. The new pipeline
		 * contains the DiscardServerHandler. As the application gets
		 * complicated, it is likely that you will add more handlers to the
		 * pipeline and extract this anonymous class into a top level class
		 * eventually.
		 */
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			public ChannelPipeline getPipeline() {
				return Channels.pipeline(new DiscardServerHandler());
			}
		});
		/**
		 * 
		 You can also set the parameters which are specific to the Channel
		 * implementation. We are writing a TCP/IP server, so we are allowed to
		 * set the socket options such as tcpNoDelay and keepAlive. Please note
		 * that the "child." prefix was added to all options. It means the
		 * options will be applied to the accepted Channels instead of the
		 * options of the ServerSocketChannel. You could do the following to set
		 * the options of the ServerSocketChannel:
		 * 
		 * bootstrap.setOption("reuseAddress", true);
		 */
		bootstrap.setOption("child.tcpNoDelay", true);
		bootstrap.setOption("child.keepAlive", true);

		bootstrap.bind(new InetSocketAddress(8080));
	}

}

3.测试:telnet localhost 8080


二、Echo Server(将请求的message回显)

1.修改DiscardServerHandler类中的messageReceived方法:

@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		/**
		 * 
		 We override the messageReceived event handler method here. This
		 * method is called with a MessageEvent, which contains the received
		 * data, whenever new data is received from a client. 
		 */

		/**
		 * A ChannelEvent object has a reference to its associated Channel.
		 * Here, the returned Channel represents the connection which received
		 * the MessageEvent. We can get the Channel and call the write method to
		 * write something back to the remote peer.
		 */
		Channel ch = e.getChannel();
		ch.write(e.getMessage());

	}

2.测试:telnet localhost 8080

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023-07-14 15:19:01.215 WARN 7308 --- [sson-netty-2-15] io.netty.util.concurrent.DefaultPromise : An exception was thrown by org.redisson.misc.RedissonPromise$$Lambda$888/0x00000008008f7440.operationComplete() java.lang.NullPointerException: null 2023-07-14 15:19:01.216 ERROR 7308 --- [sson-netty-2-15] o.r.c.SentinelConnectionManager : Can't execute SENTINEL commands on /172.24.107.11:26379 org.redisson.client.RedisException: ERR No such master with that name. channel: [id: 0x2d66827d, L:/172.23.9.103:46812 - R:/172.24.107.11:26379] command: (SENTINEL SLAVES), params: [mymaster] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:365) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:196) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:134) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:104) ~[redisson-3.13.3.jar:3.13.3] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 解决方法
07-15

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值