开始学Netty,第一天,按照文档启动一个服务
package com.netty;
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;
/**
* 英文不好,所以带上英文一起,谢谢
*
*
* */
/**
* 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
*
* DiscardServerHandler 继承与SimpleChannelHandler,
* SimpleChannelHandler实现了ChannelHandler SimpleChannelHandler提供了一个你能够重载的事件处理方法,
* 现在你最好继承SimpleChannelHandler而不是实现自己的处理接口
*
* */
public class DiscardServerHandler extends SimpleChannelHandler {
/**
* 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.
*
* 我们重载了messageReceived事件处理方法,这个方法有MessageEvent,包含了所有从客户端发送了的数据,在这个例子中,
* 我们忽略接受到的数据的处理
* */
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
}
/**
*
* 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.
*
* exceptionCaught事件处理方法将被ExceptionEvent调用,当netty产生IO异常,或者一个处理方法抛出异常信息,
* 大多情况下,我捕获的异常将被日志记录,产生问题相关的通道将被关闭,尽管这种方法的实现可以是不同的,这取决于你想怎么处理特殊情况,比如,
* 你想发送一个错误的响应信息在连接关闭前
* */
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
e.getCause().printStackTrace();
Channel ch = e.getChannel();
ch.close();
}
}
package com.netty;
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是一个创建和管理通道(Channels)和资源关系的工厂,它处理所有的IO请求和IO的执行生成通道事件(
* ChannelEvents
* ),Netty提供了一个可变的通道工厂(ChannelFactory)实现,在这个例子中我们能够提供一个服务端的应用
* NioServerSocketChannelFactory被用了
* ,要说明的是,它不创建IO线程,他提供了一个可以得到的线程的线程池通过构造函数
* 它提供了更多的控制,比如,多少线程你可以管理,或者一个安全的管理者
* */
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是一个建立服务的辅助类,你可用一个通道直接建立服务,请注意这个繁琐的程序你没有必要去做
* */
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.
*
* 现在,我们能够配置 ChannelPipelineFactory,一个新的连接将被服务端接收,一个新的 ChannelPipelin
* 将被ChannelPipelineFactory创建
* ,新的管道包含了DiscardServerHandler,当应用变得复杂,你可能添加更多的处理 管道和,扩展匿名类最终到顶级类
*
* */
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:
*
* 你能设置参数实现特殊的通道,你能写一个TCP/IP服务,你也能够设置scoket比如tcpNoDelay,keepAlive
* 请注意"child"前缀将被添加在所有选项上,他指这些选项将用与所有接收来的通道,而不是ServerSocketChannel
* 你能够都做下面的事情设置ServerSocketChannel的选项
*
* */
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
/**
* We are ready to go now. What's left is to bind to the port and to
* start the server. Here, we bind to the port 8080 of all NICs (network
* interface cards) in the machine. You can now call the bind method as
* many times as you want (with different bind addresses.)
*
* 我们开始了,让他绑定端口开始服务,我们绑定机器上的8080端口,我们能够呼叫
* 你能调用这个绑定方法任何多次
* */
bootstrap.bind(new InetSocketAddress(8080));
}
}