Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #61

Open
wants to merge 4 commits into
base: 2.0-SNAPSHOT
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 57 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,66 @@
This Repository contains the source-code for all chapters of the book [Netty in Action](http://manning.com/maurer)
by Norman Maurer and Marvin Allen Wolfthal.
# 《Netty 实战》 Netty In Action 中文版

Latest version: https://github.com/normanmaurer/netty-in-action/tree/2.0-SNAPSHOT
>代码清单已经更新到 Netty 4.1.25.final

Enjoy! Feedback and PR's welcome!
[如何评价这本书-知乎](https://www.zhihu.com/question/58838575)

[关于本书-豆瓣](https://book.douban.com/subject/27038538/)

[京东链接(现货发售):《Netty实战》([美]诺曼·毛瑞尔(Norman Maurer),马文·艾伦·沃尔夫泰尔(Marvin Allen Wolfthal)) ](https://union-click.jd.com/jdc?d=oN4CCW&come=appmessage)

[不负好时光《Netty IN ACTION》中文版《Netty实战》翻译手记](http://www.epubit.com.cn/article/1171)

[不负好时光《Netty IN ACTION》中文版《Netty实战》翻译手记(ATA内网)](https://www.atatech.org/articles/79051?flag_data_from=recommend)

![image](https://cloud.githubusercontent.com/assets/501740/25295296/94d2ef06-2715-11e7-9a2a-916d77014cfc.png)


## 内容提要

本书是为想要或者正在使用 Java 从事高性能网络编程的人而写的,循序渐进地介绍了 Netty
各个方面的内容。

本书共分为 4 个部分:第一部分详细地介绍 Netty 的相关概念以及核心组件,第二部分介绍
自定义协议经常用到的编解码器,第三部分介绍 Netty 对于应用层高级协议的支持,会覆盖常见
的协议及其在实践中的应用,第四部分是几个案例研究。此外,附录部分还会简单地介绍 Maven,
以及如何通过使用 Maven 编译和运行本书中的示例。

阅读本书不需要读者精通 Java 网络和并发编程。如果想要更加深入地理解本书背后的理念
以及 Netty 源码本身,可以系统地学习一下 Java 网络编程、 NIO、并发和异步编程以及相关的
设计模式。

## 说明

这个仓库包含了[Netty In Action](http://www.manning.com/maurer/) 这本书的中文版 [Netty实战](http://www.epubit.com.cn) 的代码清单.
为了更好地服务于读者,进行了如下方面的改进.

Prerequisites

JDK 1.7.0u71 or better
相对于英文版本([2.0-SNAPSHOT](https://github.com/ReactivePlatform/netty-in-action-cn/tree/2.0-SNAPSHOT)分支):

1. 更新了行文中的注释
2. 按照中文版本的排版进行了调整
3. 所有的代码清单以及跳转都使用了中文版书籍中的翻译


## 反馈

上游版本的更新,请直接将PR的目标调整为本仓库的`master`分支

中文版本的更新,请将PR的目标调整为本仓库的`ChineseVersion`分支

## 使用

请直接克隆本项目即可,建议对照原文查看代码.

## 勘误
[前言: 2001 => 2011](https://github.com/ReactivePlatform/netty-in-action-cn/issues/2)

-----

Prerequisites

Maven 3.3.9 or better
maven 3.3.9
JDK 8


If you want to build everything at once, from the top directory run
Expand Down
11 changes: 9 additions & 2 deletions chapter1/src/main/java/nia/chapter1/BlockingIoExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,34 @@
/**
* Created by kerr.
*
* Listing 1.1 Blocking I/O example
* 代码清单 1-1 阻塞 I/O 示例
*/
public class BlockingIoExample {

/**
* Listing 1.1 Blocking I/O example
* 代码清单 1-1 阻塞 I/O 示例
* */
public void serve(int portNumber) throws IOException {
//创建一个新的 ServerSocket,用以监听指定端口上的连接请求
ServerSocket serverSocket = new ServerSocket(portNumber);
//对accept()方法的调用将被阻塞,直到一个连接建立
Socket clientSocket = serverSocket.accept();
//这些流对象都派生于该套接字的流对象
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
String request, response;
//处理循环开始
while ((request = in.readLine()) != null) {
if ("Done".equals(request)) {
break;
}
//请求被传递给服务器的处理方法
response = processRequest(request);
//服务器的响应被发送给了客户端
out.println(response);
//继续执行处理循环
}
}

Expand Down
15 changes: 10 additions & 5 deletions chapter1/src/main/java/nia/chapter1/ConnectExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,43 @@
/**
* Created by kerr.
*
* Listing 1.3 Asynchronous connect
* 代码清单 1-3 异步地建立连接
*
* Listing 1.4 Callback in action
* 代码清单 1-4 回调实战
*/
public class ConnectExample {
private static final Channel CHANNEL_FROM_SOMEWHERE = new NioSocketChannel();

/**
* Listing 1.3 Asynchronous connect
* 代码清单 1-3 异步地建立连接
*
* Listing 1.4 Callback in action
* 代码清单 1-4 回调实战
* */
public static void connect() {
Channel channel = CHANNEL_FROM_SOMEWHERE; //reference form somewhere
// Does not block
//异步地连接到远程节点
ChannelFuture future = channel.connect(
new InetSocketAddress("192.168.0.1", 25));
//注册一个 ChannelFutureListener,以便在操作完成时获得通知
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
//检查操作的状态
if (future.isSuccess()) {
//如果操作是成功的,则创建一个 ByteBuf 以持有数据
ByteBuf buffer = Unpooled.copiedBuffer(
"Hello", Charset.defaultCharset());
//将数据异步地发送到远程节点。返回一个 ChannelFuture
ChannelFuture wf = future.channel()
.writeAndFlush(buffer);
// ...
} else {
//如果发生错误,则访问描述原因的 Throwable
Throwable cause = future.cause();
cause.printStackTrace();
}
}
});

}
}
3 changes: 2 additions & 1 deletion chapter1/src/main/java/nia/chapter1/ConnectHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
/**
* Created by kerr.
*
* Listing 1.2 ChannelHandler triggered by a callback
* 代码清单 1-2 被回调触发的 ChannelHandler
*/
public class ConnectHandler extends ChannelInboundHandlerAdapter {
@Override
//当一个新的连接已经被建立时,channelActive(ChannelHandlerContext)将会被调用
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
System.out.println(
Expand Down
8 changes: 4 additions & 4 deletions chapter1/src/main/java/nia/chapter1/package-info.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* kerr.
*
* Listing 1.1 Blocking I/O example {@link nia.chapter1.BlockingIoExample#serve(int)}
* 代码清单 1-1 阻塞 I/O 示例 {@link nia.chapter1.BlockingIoExample#serve(int)}
*
* Listing 1.2 ChannelHandler triggered by a callback {@link nia.chapter1.ConnectHandler}
* 代码清单 1-2 被回调触发的 ChannelHandler {@link nia.chapter1.ConnectHandler}
*
* Listing 1.3 Asynchronous connect {@link nia.chapter1.ConnectExample#connect()}
* 代码清单 1-3 异步地建立连接 {@link nia.chapter1.ConnectExample#connect()}
*
* Listing 1.4 Callback in action {@link nia.chapter1.ConnectExample#connect()}
* 代码清单 1-4 回调实战 {@link nia.chapter1.ConnectExample#connect()}
*/
package nia.chapter1;
4 changes: 3 additions & 1 deletion chapter10/src/main/java/nia/chapter10/ByteToCharDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
import java.util.List;

/**
* Listing 10.8 Class ByteToCharDecoder
* 代码清单 10-8 ByteToCharDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了ByteToMessageDecoder
public class ByteToCharDecoder extends ByteToMessageDecoder {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
if (in.readableBytes() >= 2) {
//将一个或者多个 Character 对象添加到传出的 List 中
out.add(in.readChar());
}
}
Expand Down
4 changes: 3 additions & 1 deletion chapter10/src/main/java/nia/chapter10/CharToByteEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
import io.netty.handler.codec.MessageToByteEncoder;

/**
* Listing 10.9 Class CharToByteEncoder
* 代码清单 9 CharToByteEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了MessageToByteEncoder
public class CharToByteEncoder extends
MessageToByteEncoder<Character> {
@Override
public void encode(ChannelHandlerContext ctx, Character msg,
ByteBuf out) throws Exception {
//将 Character 解码为 char,并将其写入到出站 ByteBuf 中
out.writeChar(msg);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import io.netty.channel.CombinedChannelDuplexHandler;

/**
* Listing 10.10 CombinedChannelDuplexHandler<I,O>
* 代码清单 CombinedChannelDuplexHandler<I,O>
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/

//通过该解码器和编码器实现参数化 CombinedByteCharCodec
public class CombinedByteCharCodec extends
CombinedChannelDuplexHandler<ByteToCharDecoder, CharToByteEncoder> {
public CombinedByteCharCodec() {
//将委托实例传递给父类
super(new ByteToCharDecoder(), new CharToByteEncoder());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
import java.util.List;

/**
* Listing 10.3 Class IntegerToStringDecoder
* 代码清单 10-3 IntegerToStringDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了MessageToMessageDecoder<Integer>
public class IntegerToStringDecoder extends
MessageToMessageDecoder<Integer> {
@Override
public void decode(ChannelHandlerContext ctx, Integer msg,
List<Object> out) throws Exception {
//将 Integer 消息转换为它的 String 表示,并将其添加到输出的 List 中
out.add(String.valueOf(msg));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@
import java.util.List;

/**
* Listing 10.6 Class IntegerToStringEncoder
* 代码清单 10-6 IntegerToStringEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了 MessageToMessageEncoder
public class IntegerToStringEncoder
extends MessageToMessageEncoder<Integer> {
@Override
public void encode(ChannelHandlerContext ctx, Integer msg,
List<Object> out) throws Exception {
//将 Integer 转换为 String,并将其添加到 List 中
out.add(String.valueOf(msg));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@
import java.util.List;

/**
* Listing 10.4 TooLongFrameException
* 代码清单 10-4 TooLongFrameException
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/

//扩展 ByteToMessageDecoder 以将字节解码为消息
public class SafeByteToMessageDecoder extends ByteToMessageDecoder {
private static final int MAX_FRAME_SIZE = 1024;
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
int readable = in.readableBytes();
//检查缓冲区中是否有超过 MAX_FRAME_SIZE 个字节
if (readable > MAX_FRAME_SIZE) {
//跳过所有的可读字节,抛出 TooLongFrameException 并通知 ChannelHandler
in.skipBytes(readable);
throw new TooLongFrameException("Frame too big!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
import io.netty.handler.codec.MessageToByteEncoder;

/**
* Listing 10.5 Class ShortToByteEncoder
* 代码清单 10-5 ShortToByteEncoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展了MessageToByteEncoder
public class ShortToByteEncoder extends MessageToByteEncoder<Short> {
@Override
public void encode(ChannelHandlerContext ctx, Short msg, ByteBuf out)
throws Exception {
//将 Short 写入 ByteBuf 中
out.writeShort(msg);
}
}
5 changes: 4 additions & 1 deletion chapter10/src/main/java/nia/chapter10/ToIntegerDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@
import java.util.List;

/**
* Listing 10.1 Class ToIntegerDecoder extends ByteToMessageDecoder
* 代码清单 10-1 ToIntegerDecoder 类扩展了 ByteToMessageDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展ByteToMessageDecoder类,以将字节解码为特定的格式
public class ToIntegerDecoder extends ByteToMessageDecoder {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
List<Object> out) throws Exception {
//检查是否至少有 4 字节可读(一个 int 的字节长度)
if (in.readableBytes() >= 4) {
//从入站 ByteBuf 中读取一个 int,并将其添加到解码消息的 List 中
out.add(in.readInt());
}
}
Expand Down
6 changes: 4 additions & 2 deletions chapter10/src/main/java/nia/chapter10/ToIntegerDecoder2.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@
import java.util.List;

/**
* Listing 10.2 Class ToIntegerDecoder2 extends ReplayingDecoder
* 代码清单 10-2 ToIntegerDecoder2 类扩展了 ReplayingDecoder
*
* @author <a href="mailto:[email protected]">Norman Maurer</a>
*/
//扩展 ReplayingDecoder<Void> 以将字节解码为消息
public class ToIntegerDecoder2 extends ReplayingDecoder<Void> {

@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in,
public void decode(ChannelHandlerContext ctx, ByteBuf in, //传入的 ByteBuf 是 ReplayingDecoderByteBuf
List<Object> out) throws Exception {
//从入站 ByteBuf 中读取 一个 int,并将其添加到解码消息的 List 中
out.add(in.readInt());
}
}
Expand Down
Loading