一、简单的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