SlideShare ist ein Scribd-Unternehmen logo
1 von 27
Downloaden Sie, um offline zu lesen
 
2 
Solving common network 
programming problems 
In chapter 1, you have learned core concepts and classes in Netty to build a 
networking­based application. In this chapter, we will cover common problems and 
how to solve when building network­based application. You will learn how to: 
● Getting the local SocketAddress and the remote SocketAddress 
● Sending and receiving data in Stream­based TCP/IP Transport 
● Sending data in POJO way 
● Listening multiple sockets in one Netty instance 
● Building your own protocol servers and clients with Custom Codec 
● Counting Server Bandwidth in ChannelHandler 
● Checking Heartbeat Server using UDP protocol 
● Using Stream Control Transmission Protocol (SCTP) codec 
● Building simple FTP server 
● Building server RPC (Remote Procedure Call) with Apache Avro and Netty 
● Building simple HTTP file downloader 
Introduction 
In chapter 2, from recipe 2.1 to 2.6 will guide you how to use Netty in common use 
cases,  with most important concept is Codec. From recipe 2.7 to 2.12,  we will cover 
some examples with popular network protocol, such as TCP/IP, UDP , SCTP, FTP , RPC 
with Apache Avro,  downloading file from HTTP and building a simple Pub­Sub Netty 
server. 
 
 
Getting ready 
Make sure you check out this code at the Git repository of book 
https://github.com/trieu/netty­cookbook 
In this chapter, we would use the class ​netty.cookbook.common.BootstrapTemplate 
to create common Netty’s bootstrap for both server code and client code. 
Recipe 2.1 Getting the local SocketAddress and the 
remote SocketAddress 
Problem: 
Your server needs to log the remote or local SocketAddress, this recipe could be useful 
for debugging.  
How to do it … 
In any implemented class of ChannelInboundHandler or ChannelOutboundHandler, 
your code must override the method “channelActive” and you can use the instance of 
ChannelHandlerContext to get all information about the active connected channel. 
This example code would illustrate how to do: 
public​ ​void​ channelActive​(​ChannelHandlerContext​ ctx) 
throws​ ​Exception​ { 
InetSocketAddress​ localAddr ​=​ ​(​InetSocketAddress​) 
ctx​.​channel​().​localAddress​(); 
logger​.​info​(​String​.​format​(​"localAddress.hostname 
%s"​,​localAddr​.​getHostName​())); 
logger​.​info​(​String​.​format​(​"localAddress.port %s"​,​localAddr​.​getPort​())); 
  
InetSocketAddress​ remoteAddr ​=​ ​(​InetSocketAddress​) 
ctx​.​channel​().​remoteAddress​(); 
logger​.​info​(​String​.​format​(​"remoteAddress.hostname 
%s"​,​remoteAddr​.​getHostName​())); 
logger​.​info​(​String​.​format​(​"remoteAddress.port 
%s"​,​remoteAddr​.​getPort​())); 
} 
 
 
How it works 
We can see the output from above code. 
2014​­​11​­​27​ ​06​:​11​:​06​ INFO  ​LoggingHandler​:​100​ ​­​ ​[​id​:​ ​0x8db2146f​]​ REGISTERED 
2014​­​11​­​27​ ​06​:​11​:​06​ INFO  ​LoggingHandler​:​100​ ​­​ ​[​id​:​ ​0x8db2146f​] 
BIND​(​0.0​.​0.0​/​0.0​.​0.0​:​8007) 
2014​­​11​­​27​ ​06​:​11​:​06​ INFO  ​LoggingHandler​:​100​ ​­​ ​[​id​:​ ​0x8db2146f​, 
/​0​:​0​:​0​:​0​:​0​:​0​:​0​:​0​:​8007​]​ ACTIVE 
2014​­​11​­​27​ ​06​:​11​:​12​ INFO  ​LoggingHandler​:​100​ ​­​ ​[​id​:​ ​0x8db2146f​, 
/​0​:​0​:​0​:​0​:​0​:​0​:​0​:​0​:​8007​]​ RECEIVED​:​ ​[​id​:​ ​0x90524633​,​ ​/127.0.0.1:46697 => 
/​127.0​.​0.1​:​8007] 
2014​­​11​­​27​ ​06​:​11​:​12​ INFO  ​PurchaseServer​:​47​ ​­​ localAddress​.​hostname localhost 
2014​­​11​­​27​ ​06​:​11​:​12​ INFO  ​PurchaseServer​:​48​ ​­​ localAddress​.​port ​8007 
2014​­​11​­​27​ ​06​:​11​:​12​ INFO  ​PurchaseServer​:​51​ ​­​ remoteAddress​.​hostname localhost 
2014​­​11​­​27​ ​06​:​11​:​12​ INFO  ​PurchaseServer​:​52​ ​­​ remoteAddress​.​port ​46697 
Recipe 2.2 Sending and receiving data in 
Stream­based TCP/IP Transport 
Problem: 
When sending data over the TCP/IP, data usually must be divided into smaller packets. 
That’s the mechanism of a stream­based transport such as TCP/IP. For example, if you 
want to send a long messages, the protocol transport itself  would divide the message 
as independent set of bytes. Also, there is no guarantee that what you could receive is 
exactly what your remote peer sent. 
Solution: 
Netty provides an extensible class which helps you solve this problem more elegant. 
One simple way you could do , by extending the class ByteToMessageDecoder or 
ReplayingDecoder to encode and decode received data into one or more meaningful 
frames instead of bytes. It’s also safer for sending and receiving a large data message 
in stream­based transport such as TCP/IP. 
 
 
 
How to do it … 
We could split MessageClientHandler into two handlers: 
● MessageDecoder which deals with the fragmentation issue, and 
● the initial simple version of MessageClientHandler. 
Netty provides extensible classes which simplify  code you would write, one of 
common way to send/receive string message in Netty is using StringEncoder and 
StringDecoder. Let’s see how simple code: 
The sender class: 
public​ ​class​ ​Sender​ { 
static​ ​final​ ​int​ PORT ​=​ ​8007; 
static​ ​final​ ​String​ HOST ​=​ ​"127.0.0.1"; 
 
public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​InterruptedException​ ​{   
final​ ​String​ msg ​=​ ​"This is a long message"; 
  ChannelInitializer​<​SocketChannel​>​ initializer ​=​ ​new 
ChannelInitializer​<​SocketChannel​>()​ { 
@Override 
 
 
public​ ​void​ initChannel​(​SocketChannel​ ch​)​ ​throws​ ​Exception 
{ 
ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
p​.​addLast​(​new​ ​StringEncoder​()); 
p​.​addLast​(​new​ ​StringDecoder​()); 
p​.​addLast​(​new​ ​ChannelInboundHandlerAdapter​()​ { 
@Override 
public​ ​void 
channelActive​(​ChannelHandlerContext​ ctx) 
throws​ ​Exception​ { 
//on ready to send 
ctx​.​writeAndFlush​(​msg​); 
} 
@Override 
public​ ​void 
channelRead​(​ChannelHandlerContext​ ctx, 
Object​ data​)​ ​throws​ ​Exception 
{ 
//on receive 
System​.​out​.​println​(​"got "​ ​+​ data​); 
} 
}); 
} 
}; 
BootstrapTemplate​.​newClientBootstrap​(​HOST​,​ PORT​,​ initializer ​); 
Thread​.​sleep​(​5000​); 
} 
} 
The receiver class 
public​ ​class​ ​Receiver​ { 
static​ ​final​ ​int​ PORT ​=​ ​8007; 
static​ ​final​ ​String​ HOST ​=​ ​"127.0.0.1"; 
public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​Exception​ { 
 
 
ChannelInitializer​<​SocketChannel​>​ initializer ​=​ ​new 
ChannelInitializer​<​SocketChannel​>()​ { 
@Override 
public​ ​void​ initChannel​(​SocketChannel​ ch​)​ ​throws​ ​Exception 
{ 
ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
p​.​addLast​(​new​ ​StringEncoder​()); 
p​.​addLast​(​new​ ​StringDecoder​()); 
p​.​addLast​(​new​ ​ChannelInboundHandlerAdapter​()​ { 
@Override 
public​ ​void 
channelRead​(​ChannelHandlerContext​ ctx​,​ ​Object​ msg​)​ ​throws​ ​Exception​ { 
System​.​out​.​println​(​msg​); 
ctx​.​close​(); 
} 
}); 
} 
}; 
BootstrapTemplate​.​newServerBootstrap​(​HOST​,​ PORT​,​ initializer​); 
} 
} 
Recipe 2.3 Sending data in POJO way 
Problem 
The POJO or  Plain Old Java Object, is common way to encoding business logic into 
regular java objects rather than using Entity Beans. Netty supports encoding/decoding 
object into ByteBuf and vice versa. 
Example we have this business object for modelling the data of a purchase transaction 
between user and e­commerce back­end server.  
 
public​ ​class​ ​PurchaseData​ ​implements​ ​Serializable{ 
private​ ​final​ ​int​ itemId; 
 
 
private​ ​final​ ​float​ price; 
private​ ​final​ ​String​ buyer; 
private​ ​final​ ​String​ seller; 
private​ ​final​ ​int​ unixTime; 
private​ ​final​ ​boolean​ processed; 
How to do it … 
Let’s check this diagram 
 
Netty supports 2 classes, ObjectDecoder and ObjectEncoder, that simplifies how we 
decoding/encoding POJO objects 
In the method initChannel, add this code for POJO codec: 
        ​ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
 ​ClassResolver​ cl ​=​ ​ClassResolvers​.​weakCachingConcurrentResolver​(​null​); 
 p​.​addLast​(​"decoder"​,​ ​new​ ​ObjectDecoder​(​cl​));    
 p​.​addLast​(​"encoder"​,​ ​new​ ​ObjectEncoder​());  
Here is the full code of PurchaseData class 
public​ ​class​ ​PurchaseData​ ​implements​ ​Serializable{ 
private​ ​static​ ​final​ ​long​ serialVersionUID ​=​ ​­​5467453661148034694L; 
private​ ​final​ ​int​ itemId; 
 
 
private​ ​final​ ​float​ price; 
private​ ​final​ ​String​ buyer; 
private​ ​final​ ​String​ seller; 
private​ ​final​ ​int​ unixTime; 
private​ ​final​ ​boolean​ processed; 
public​ ​PurchaseData​(​int​ itemId​,​ ​float​ price​,​ ​String​ buyer​,​ ​String 
seller, ​int​ unixTime​,​ ​boolean​ processed​)​ { 
super​(); 
this​.​itemId ​=​ itemId; 
this​.​price ​=​ price; 
this​.​buyer ​=​ buyer; 
this​.​seller ​=​ seller; 
this​.​unixTime ​=​ unixTime; 
this​.​processed ​=​ processed; 
}  
public​ ​PurchaseData​(​Object​ obj​,​ ​boolean​ processed​)​ { 
super​(); 
PurchaseData​ data ​=​ ​(​PurchaseData​)​obj; 
this​.​itemId ​=​ data​.​itemId; 
this​.​price ​=​ data​.​price; 
this​.​buyer ​=​ data​.​buyer; 
this​.​seller ​=​ data​.​seller; 
this​.​unixTime ​=​ data​.​unixTime; 
this​.​processed ​=​ processed; 
} 
The code of PurchaseServer 
ChannelInitializer​<​SocketChannel​>​ initializer ​=​ ​new 
ChannelInitializer​<​SocketChannel​>()​ { 
@Override 
public​ ​void​ initChannel​(​SocketChannel​ ch​)​ ​throws​ ​Exception​ { 
ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
p​.​addLast​(​new​ ​PurchaseDataDecoder​()); 
p​.​addLast​(​new​ ​PurchaseDataEncoder​()); 
 
 
p​.​addLast​(​new​ ​ChannelInboundHandlerAdapter​()​ { 
@Override 
public​ ​void​ channelRead​(​ChannelHandlerContext​ ctx, 
Object​ data​)​ ​throws​ ​Exception​ { 
System​.​out​.​println​(​"processed Purchase "​ ​+​ data​); 
PurchaseData​ processed ​=​ ​new​ ​PurchaseData​(​data​, 
true​); 
ctx​.​writeAndFlush​(​processed​); 
} 
}); 
} 
}; 
BootstrapTemplate​.​newServerBootstrap​(​HOST​,​ PORT​,​ initializer​); 
The code of PurchaseClient 
public​ ​class​ ​PurchaseClient​ { 
String​ host​;​ ​int​ port; 
    ​public​ ​PurchaseClient​(​String​ host​,​ ​int​ port​)​ { 
super​(); 
this​.​host ​=​ host; 
this​.​port ​=​ port; 
}   
    ​public​ ​PurchaseClient​ send​(​PurchaseData​ message​,​ ​CallbackProcessor 
asynchCall​)​ ​throws​ ​Exception{ 
  ChannelHandler​ clientHandler ​=​ ​new​ ​PurchaseClientHandler​(​message​, 
asynchCall​); 
  ChannelInitializer​<​SocketChannel​>​ initializer ​=​ ​new 
ChannelInitializer​<​SocketChannel​>()​ { 
@Override 
public​ ​void​ initChannel​(​SocketChannel​ ch​)​ ​throws​ ​Exception 
{ 
ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
p​.​addLast​(​new​ ​PurchaseDataDecoder​()); 
p​.​addLast​(​new​ ​PurchaseDataEncoder​()); 
p​.​addLast​(​clientHandler​); 
 
 
} 
}; 
BootstrapTemplate​.​newTcpClientBootstrap​(​host​,​ port​,​ initializer 
); 
  return​ ​this; 
    ​}   
    ​public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​Exception​ ​{   
  int​ time ​=​ ​(​int​)​ ​(​System​.​currentTimeMillis​()​ ​/​ ​1000L​); 
PurchaseData​ data ​=​ ​new​ ​PurchaseData​(​1001​,​ ​499.99f​,​ ​"Trieu"​, 
"Amazon"​,​ time​,​ ​false​ ​); 
  new​ ​PurchaseClient​(​"127.0.0.1"​,​8007​).​send​(​data​,​ rs ​­>​ { 
  System​.​out​.​println​(​rs​);   
  });   
    } 
} 
Recipe 2.4 Listening multiple sockets in one Netty 
instance 
Problem: 
In networking development, sometimes you want your server listen multiple sockets 
in one instance. Example , you could implement a HTTP server , which would listen in 
2 sockets. The first one for public, that serves all traffic requests from Internet.  The 
second one for private usage, which only internal networking management or 
networking monitoring. 
How to do it  
We  use 2 independent objects of ServerBootstrap to solve this problem. Each of them 
bind to different socket, so the request would be processed in 2 independent 
instances of ChannelHandler. Loot at this code: 
 
try​ ​{   
//public service processor 
 
 
ServerBootstrap​ publicServerBootstrap ​=​ ​new​ ​ServerBootstrap​();   
publicServerBootstrap​.​group​(​bossGroup​,​workerGroup​).​channel​(​NioServerSocketChanne
l​.​class​); 
 
//bind to public access host info 
Channel​ ch1; 
if​(​"*"​.​equals​(​ip​)){ 
ch1 ​=​ publicServerBootstrap​.​bind​(​port​).​sync​().​channel​(); 
}​ ​else​ { 
ch1 ​=​ publicServerBootstrap​.​bind​(​ip​,​ port​).​sync​().​channel​(); 
} 
ch1​.​config​().​setConnectTimeoutMillis​(​1800​); 
//admin service processor 
ServerBootstrap​ adminServerBootstrap ​=​ ​new​ ​ServerBootstrap​();   
adminServerBootstrap​.​group​(​bossGroup​,​workerGroup​).​channel​(​NioServerSocketChannel
.​class) 
.​childOption​(​ChannelOption​.​TCP_NODELAY​,​ ​false​) 
.​childOption​(​ChannelOption​.​SO_KEEPALIVE​,​ ​false)   
.​childHandler​(​new 
PrivateHttpServerInitializer​(​DEFAULT_CLASSPATH​,​this​.​privatePoolSize ​)); 
 
//bind to private access (for administrator only) host info, default 10000 
Channel​ ch2; 
if​(​"*"​.​equals​(​ip​)){ 
ch2 ​=​ adminServerBootstrap​.​bind​(​privatePort​).​sync​().​channel​(); 
}​ ​else​ { 
ch2 ​=​ adminServerBootstrap​.​bind​(​ip​,​privatePort​).​sync​().​channel​(); 
}   
ch2​.​config​().​setConnectTimeoutMillis​(​1800​);   
LogUtil​.​i​(​"publicServerBootstrap "​,​ ​"is started and listening at "​ ​+​ ​this​.​ip ​+ 
":"​ ​+​ ​this​.​port​); 
LogUtil​.​i​(​"adminServerBootstrap "​,​ ​"is started and listening at "​ ​+​ ​this​.​ip ​+ 
":"​ ​+​ privatePort​); 
ch1​.​closeFuture​().​sync​();   
 
 
ch2​.​closeFuture​().​sync​(); 
System​.​out​.​println​(​"Shutdown..."​); 
Recipe 2.5 Counting Server Bandwidth Meter 
Problem 
One common problem in network monitoring is how we can measure the use of 
bandwidth in your Netty application. In this recipe , we will cover how to do in by 
adding modification in pipeline and it will measure the size of sent/received 
ByteBuffer. 
How to do it 
 
Look at the diagram, we would hook the code into decode codec and encode codec. 
This code illustrates the solution 
public​ ​class​ ​NettyMonitorIO​ { 
static​ ​final​ ​DateFormat​ DATE_TIME_FORMAT ​=​ ​new 
SimpleDateFormat​(​"yyyy­MM­dd HH:mm"​); 
static​ ​ConcurrentMap​<​String​,​ ​Long​>​ dataOutStats ​=​ ​new 
ConcurrentHashMap​<​String​,​ ​Long​>(); 
static​ ​ConcurrentMap​<​String​,​ ​Long​>​ dataInStats ​=​ ​new 
ConcurrentHashMap​<​String​,​ ​Long​>(); 
 
 
public​ ​static​ ​long​ updateDataOut​(​ByteBuf​ buf​)​ { 
String​ time ​=​ DATE_TIME_FORMAT​.​format​(​new​ ​Date​()); 
long​ c ​=​ dataOutStats​.​getOrDefault​(​time​,​ ​0L​)​ ​+ 
buf​.​readableBytes​(); 
dataOutStats​.​put​(​time​,​ c​); 
return​ c; 
}  
public​ ​static​ ​long​ updateDataIn​(​ByteBuf​ buf​)​ { 
String​ time ​=​ DATE_TIME_FORMAT​.​format​(​new​ ​Date​()); 
long​ c ​=​ dataInStats​.​getOrDefault​(​time​,​ ​0L​)​ ​+ 
buf​.​writableBytes​(); 
dataInStats​.​put​(​time​,​ c​); 
return​ c; 
} 
static​ { 
new​ ​Timer​(​true​).​schedule​(​new​ ​TimerTask​()​ { 
@Override 
public​ ​void​ run​()​ { 
System​.​out​.​println​(​"­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­"​); 
System​.​out​.​println​(​"Data In Stats:"​); 
dataInStats​.​forEach​((​String​ key​,​ ​Long​ val​)­>{ 
LogUtil​.​println​(​key ​+​ ​" : "​+​val​); 
}); 
System​.​out​.​println​(​"Data Out Stats:"​); 
dataOutStats​.​forEach​((​String​ key​,​ ​Long​ val​)­>{ 
LogUtil​.​println​(​key ​+​ ​" : "​+​val​); 
}); 
} 
},​ ​2000​,​ ​2000​); 
} 
} 
public​ ​class​ ​PurchaseDataDecoder​ ​extends​ ​ObjectDecoder​ { 
 
 
public​ ​PurchaseDataDecoder​()​ { 
super​(​ClassResolvers​.​weakCachingConcurrentResolver​(​null​));  
} 
@Override 
protected​ ​Object​ decode​(​ChannelHandlerContext​ ctx​,​ ​ByteBuf​ buf) 
throws​ ​Exception​ { 
Object​ ​object​ ​=​ ​super​.​decode​(​ctx​,​ buf​); 
NettyMonitorIO​.​updateDataIn​(​buf​); 
return​ ​object; 
} 
} 
public​ ​class​ ​PurchaseDataEncoder​ ​extends​ ​ObjectEncoder​ { 
@Override 
protected​ ​void​ encode​(​ChannelHandlerContext​ ctx​,​ ​Serializable​ msg​, 
ByteBuf​ buf​)​ ​throws​ ​Exception​ ​{  
super​.​encode​(​ctx​,​ msg​,​ buf​); 
NettyMonitorIO​.​updateDataOut​(​buf​); 
} 
} 
 
How it works 
2014​­​12​­​05​ ​10​:​56​:​35​ INFO  ​LoggingHandler​:​101​ ​­​ ​[​id​:​ ​0x1fbe5190​]​ REGISTERED 
2014​­​12​­​05​ ​10​:​56​:​35​ INFO  ​LoggingHandler​:​101​ ​­​ ​[​id​:​ ​0x1fbe5190​] 
BIND​(​0.0​.​0.0​/​0.0​.​0.0​:​8007) 
2014​­​12​­​05​ ​10​:​56​:​35​ INFO  ​LoggingHandler​:​101​ ​­​ ​[​id​:​ ​0x1fbe5190​,​ ​/​0​:​0​:​0​:​0​:​0​:​0​:​0​:​0​:​8007​] 
ACTIVE 
2014​­​12​­​05​ ​10​:​56​:​39​ INFO  ​LoggingHandler​:​101​ ​­​ ​[​id​:​ ​0x1fbe5190​,​ ​/​0​:​0​:​0​:​0​:​0​:​0​:​0​:​0​:​8007​] 
RECEIVED​:​ ​[​id​:​ ​0x10fdf42c​,​ ​/127.0.0.1:33991 => /​127.0​.​0.1​:​8007] 
2014​­​12​­​05​ ​10​:​56​:​39​ INFO  ​PurchaseServer​:​33​ ​­​ localAddress​.​hostname localhost 
2014​­​12​­​05​ ​10​:​56​:​39​ INFO  ​PurchaseServer​:​34​ ​­​ localAddress​.​port ​8007 
2014​­​12​­​05​ ​10​:​56​:​39​ INFO  ​PurchaseServer​:​37​ ​­​ remoteAddress​.​hostname localhost 
2014​­​12​­​05​ ​10​:​56​:​39​ INFO  ​PurchaseServer​:​38​ ​­​ remoteAddress​.​port ​33991 
 
 
processed ​Purchase 
{​"itemId"​:​1001​,​"price"​:​499.99​,​"buyer"​:​"Trieu"​,​"seller"​:​"Amazon"​,​"unixTime"​:​1417751798​,​"
processed"​:​false} 
­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
Data​ ​In​ ​Stats: 
2014​­​12​­​05​ ​10​:​56​ ​:​ ​942 
Data​ ​Out​ ​Stats: 
2014​­​12​­​05​ ​10​:​56​ ​:​ ​82 
 
Recipe 2.6 Checking Heartbeat Server using UDP 
Problem 
Sometimes we don’t  want to use TCP/IP for transmitting data, because the reliability 
is not our priority. By  UDP is a connection­less protocol, so it’s more better than 
TCP/IP  in many applications, such as: 
● Broadcasting message in a publish­subscribe kind of application. 
● One­way "logging" activity can be handled nicely with UDP packets 
● Implementing "heartbeat" or "I'm alive" messages, because we want to get a 
simple answer to another server quickly 
● Video streaming and especially VoIP, voice chat ,..(e.g. Skype), that a dropped 
packet is not such a big deal. 
How to do it … 
At server, loading Bootrap object with “option(ChannelOption.SO_BROADCAST, true)” 
The handler of server should extend SimpleChannelInboundHandler.  
The server UDP socket is bind at 255.255.255.255, port 8080 
Suppose we have an ImportantServer , that must be monitored. 
public​ ​class​ ​ImportantServer​ { 
private​ ​static​ ​final​ ​int​ PORT ​=​ ​8080; 
public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​Exception​ { 
EventLoopGroup​ loopGroup ​=​ ​new​ ​NioEventLoopGroup​(); 
 
 
try​ ​{  
BootstrapTemplate​.​newBootstrapUDP​(​loopGroup​,​ ​new 
HeartBeatHandler​(),​ PORT) 
.​sync​().​channel​().​closeFuture​().​await​(); 
}​ ​finally​ { 
loopGroup​.​shutdownGracefully​(); 
} 
} 
} 
 
The code method “channelRead0” of HeartBeatHandler  
protected​ ​void​ channelRead0​(​ChannelHandlerContext​ ctx​,​ ​DatagramPacket​ packet​) 
throws​ ​Exception​ { 
System​.​err​.​println​(​packet​); 
String​ s ​=​ packet​.​content​().​toString​(​CharsetUtil​.​UTF_8​); 
System​.​out​.​println​(​s​); 
ByteBuf​ buf ​=​ ​Unpooled​.​copiedBuffer​(​"I'm alive at "​+​new​ ​Date​(), 
CharsetUtil​.​UTF_8​); 
ctx​.​write​(​new​ ​DatagramPacket​(​buf​,​ packet​.​sender​())); 
} 
The ServerHealthChecker, which uses UDP as main protocol  
SimpleChannelInboundHandler​<​DatagramPacket​>​ handler ​=​ ​new 
SimpleChannelInboundHandler​<​DatagramPacket​>()​ { 
@Override 
public​ ​void​ exceptionCaught​(​ChannelHandlerContext​ ctx​, 
Throwable​ cause​)​ { 
cause​.​printStackTrace​(); 
ctx​.​close​(); 
} 
@Override 
protected​ ​void​ channelRead0​(​ChannelHandlerContext​ ctx​, 
DatagramPacket​ msg) 
throws​ ​Exception​ { 
 
 
String​ response ​= 
msg​.​content​().​toString​(​CharsetUtil​.​UTF_8​); 
System​.​out​.​println​(​"LogClient: "​ ​+​ response​); 
ctx​.​close​(); 
} 
}; 
EventLoopGroup​ loopGroup ​=​ ​new​ ​NioEventLoopGroup​(); 
try​ { 
ChannelFuture​ chnlFuture ​= 
BootstrapTemplate​.​newBootstrapUDP​(​loopGroup​,​ handler​,​ ​0​); 
Channel​ ch ​=​ chnlFuture​.​sync​().​channel​(); 
// Broadcast to port 8080 
InetSocketAddress​ udpAddr ​=​  ​new 
InetSocketAddress​(​"255.255.255.255"​,​ PORT​); 
for​ ​(​int​ i​=​0​;​i​<​5​;​i​++)​ { 
ByteBuf​ buf ​=​ ​Unpooled​.​copiedBuffer​(​"ping at "​ ​+ 
new​ ​Date​(),​CharsetUtil​.​UTF_8​); 
ch​.​write​(​new​ ​DatagramPacket​(​buf​,​udpAddr​)); 
Thread​.​sleep​(​1000​); 
} 
ch​.​flush​().​closeFuture​().​sync​(); 
//If the channel is not closed within 5 seconds, quit
 
if​ ​(!​ch​.​closeFuture​().​await​(​10000​))​ { 
System​.​err​.​println​(​"request timed out."​); 
} 
}​ ​finally​ { 
loopGroup​.​shutdownGracefully​(); 
} 
 
 
 
Recipe 2.9 Using Stream Control Transmission 
Protocol (SCTP) codec 
Getting to know 
SCTP (Stream Control Transmission Protocol) is a protocol for transmitting multiple 
streams of data at the same time between two end points that have established a 
connection in a network. Sometimes referred to as "next generation TCP" 
(Transmission Control Protocol). 
SCTP is a natural candidate to support telephone signaling over the Internet as well as 
other message­oriented applications. Applications that require high degrees of fault 
tolerance, such as online banking and stock market transaction exchanges, will benefit 
from SCTP's multihoming. 
You can follow this link for more information about SCTP protocol 
http://www.ibm.com/developerworks/library/l­sctp 
Problem 
Your want to build a SCTP server that accepts and prints out all received messages, 
and SCTP client that send multipe messages at the same time. 
Getting ready 
In linux OS you need to install lksctp library as linux doesn't have this installed by 
default. 
● Fedora: sudo yum install lksctp­tools­1.0.9­1.fc10 or 
● Ubuntu: sudo apt­get install lksctp­tools 
How to do it ... 
In SCTP server bootstrap 
EventLoopGroup​ mainLoop ​=​ ​new​ ​NioEventLoopGroup​(​1​); 
EventLoopGroup​ workerLoop ​=​ ​new​ ​NioEventLoopGroup​(); 
try​ { 
       ​ChannelFuture​ f ​=​ ​new​ ​ServerBootstrap​().​group​(​mainLoop​,​ workerLoop) 
             ​.​channel​(​NioSctpServerChannel​.​class) 
 
 
             ​.​option​(​ChannelOption​.​SO_BACKLOG​,​ ​100) 
             ​.​handler​(​new​ ​LoggingHandler​(​LogLevel​.​INFO​)) 
             ​.​childHandler​(​new​ ​ChannelInitializer​<​SctpChannel​>()​ { 
                 ​@Override 
                 ​public​ ​void​ initChannel​(​SctpChannel​ ch​)​ ​throws​ ​Exception​ { 
   ​ChannelPipeline​ p ​=​ ch​.​pipeline​();   
                     p​.​addLast​(​new​ ​SimpleSctpServerHandler​()); 
                 } 
             ​}).​bind​(​PORT​).​sync​();   
            f​.​channel​().​closeFuture​().​sync​(); 
        ​}​ ​finally​ ​{   
            mainLoop​.​shutdownGracefully​(); 
            workerLoop​.​shutdownGracefully​(); 
        } 
} 
In the code of SCTP Server handler, at channelRead, the message is instance of 
SctpMessage 
public​ ​void​ channelRead​(​ChannelHandlerContext​ ctx​,​ ​Object​ msg​)​ { 
  System​.​out​.​println​(​msg​); 
  if​(​msg ​instanceof​ ​SctpMessage​){  
  SctpMessage​ sctpMsg ​=​ ​(​SctpMessage​)​ msg; 
 
System​.​out​.​println​(​sctpMsg​.​content​().​toString​(​CharsetUtil​.​UTF_8​)); 
  ctx​.​write​(​sctpMsg​);  
  }   
    } 
The SCTP client bootstrap 
 ​EventLoopGroup​ loopGroup ​=​ ​new​ ​NioEventLoopGroup​(); 
        ​try​ ​{   
  ChannelFuture​ f ​=​ ​new​ ​Bootstrap​().​group​(​loopGroup) 
             ​.​channel​(​NioSctpChannel​.​class) 
             ​// set SCTP option 
 
 
             ​.​option​(​SctpChannelOption​.​SCTP_NODELAY​,​ ​true​)  
             ​.​handler​(​new​ ​ChannelInitializer​<​SctpChannel​>()​ { 
                 ​@Override 
                 ​public​ ​void​ initChannel​(​SctpChannel​ ch​)​ ​throws​ ​Exception​ { 
   ​ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
                     p​.​addLast​(​new​ ​SimpleSctpClientHandler​()); 
                 } 
             ​}).​connect​(​HOST​,​ PORT​).​sync​();   
            f​.​channel​().​closeFuture​().​sync​(); 
        ​}​ ​finally​ { 
  loopGroup​.​shutdownGracefully​(); 
        } 
The SCTP client handler code 
 ​private​ ​final​ ​ByteBuf​ firstMessage​,​ secondMessage; 
    ​public​ ​SimpleSctpClientHandler​()​ { 
        firstMessage ​=​ ​Unpooled​.​copiedBuffer​(​"first message"​,​CharsetUtil​.​UTF_8​); 
        secondMessage ​=​ ​Unpooled​.​copiedBuffer​(​"second 
message"​,​CharsetUtil​.​UTF_8​); 
    } 
    ​@Override 
    ​public​ ​void​ channelActive​(​ChannelHandlerContext​ ctx​)​ { 
        ctx​.​write​(​new​ ​SctpMessage​(​0​,​ ​0​,​ firstMessage​)); 
        ctx​.​write​(​new​ ​SctpMessage​(​0​,​ ​0​,​ secondMessage​)); 
        ctx​.​flush​(); 
    } 
 
Recipe 2.10 Building simple FTP server 
Problem 
FTP  or File Transfer Protocol is most common protocol for transferring files between 
client and server. We will learn to use Netty to build a simple FTP server in this recipe. 
 
 
Getting ready 
Due to the core Netty 4 is still support completely FTP Channel Handler, so for rapid 
development, you should check out this source code  
https://github.com/codingtony/netty­ftp­receiver 
It’s the Netty handler, partial implementation of RFC 959 "File Transfer Protocol (FTP)" 
for receiving FTP files.  
How to do it … 
You define the template for receiving data with FTP protocol. 
Example code of the data receiver class : 
class​ ​FileReceiver​ ​implements​ ​DataReceiver​ { 
    ​@Override 
    ​public​ ​void​ receive​(​String​ name​,​ ​InputStream​ data​)​ ​throws​ ​IOException​ { 
        ​System​.​out​.​println​(​"got file: ["​ ​+​ name ​+​ ​"]"​); 
        ​//copy to local folder 
        ​Files​.​copy​(​data​,​ ​new​ ​File​(​"./data/"​+​name​).​toPath​());   
    } 
} 
In Netty’s bootstrap code, add 2 classes: CrlfStringDecoder and FtpServerHandler to 
ChannelPipeline 
public​ ​class​ ​SimpleServerFTP​ { 
public​ ​static​ ​void​ main​(​String​...​ args​)​ ​throws​ ​Exception​ { 
DataReceiver​ dataReceiver ​=​ ​new​ ​FileReceiver​(); 
  final​ ​DefaultCommandExecutionTemplate​ tpl ​=​ ​new 
DefaultCommandExecutionTemplate​(​dataReceiver​);   
  ChannelInitializer​<​SocketChannel​>​ initializer ​=​ ​new 
ChannelInitializer​<​SocketChannel​>()​ { 
@Override 
protected​ ​void​ initChannel​(​SocketChannel​ ch​)​ ​throws 
Exception​ { 
ChannelPipeline​ p ​=​ ch​.​pipeline​(); 
            p​.​addLast​(​new​ ​CrlfStringDecoder​()); 
 
 
            p​.​addLast​(​new​ ​FtpServerHandler​(​tpl​)); 
} 
}; 
  BootstrapTemplate​.​newServerBootstrap​(​"127.0.0.1"​,​ ​2121​,​ initializer​); 
} 
} 
 
Recipe 2.10 Building server RPC (Remote 
Procedure Call) with Apache Avro 
Problem 
How could we make distributed programming look like as much as possible like 
normal programming ?  
One of simple solution is the RPC or the Remote Procedure Call, is a well­understood 
mechanism and popular in distributed programming. Currently, Netty framework is 
not fully implemented RPC, but there are many good and open source projects do this 
job very well. 
In this recipe, we will use Apache Avro, a data serialization system, which supports 
RPC with Netty as core library. 
To illustrate RPC, we would build a simple server to receive mail and a client to send 
messages. 
Getting to know 
Avro is a remote procedure call, fully supports data serialization framework and 
developed within Apache's Hadoop project. It uses JSON for defining data types and 
protocols, and serializes data in a compact binary format. Main features: 
● Rich and complex data structures 
● A compact, fast and binary data format for streaming data between hosts 
● A container file, to store persistent data. 
● Remote procedure call (RPC) for distributed computing 
● Simple integration with dynamic languages, such as Python, Ruby, … so 
integration between independent services 
 
 
Getting ready 
Make sure you check out this code at the Git repository of book 
https://github.com/trieu/netty­cookbook 
The full code at the package netty.cookbook.chapter2.recipe10 
 
How to do it … 
Optional step, first on all, we need to create Mail protocol , or the Interface Definition 
Language to specify RPC call and return types.  
In the current directory of netty­cookbook’s code, go to tools and run 
java ​­​jar avro​­​tools​­​1.7​.​7.jar​ compile protocol ​../​src​/​main​/​avro​/​mail​.​avpr 
../​src​/​main​/​java/ 
In the ProxyServerAvroRPC  
public​ ​class​ ​ProxyServerAvroRPC​ { 
public​ ​static​ ​class​ ​MailImpl​ ​implements​ ​Mail​ { 
public​ ​Utf8​ send​(​Message​ message​)​ ​{  
String​ s ​=​ ​String​.​format​(​"message details, to:%s from:%s 
body:%s"​,​ message​.​getTo​(),​  message​.​getFrom​(),​ message​.​getBody​()); 
LogUtil​.​println​(​s​); 
return​ ​new​ ​Utf8​(​"Sent OK to "​+​ message​.​getTo​()); 
} 
} 
private​ ​static​ ​Server​ server; 
static​ ​void​ startServer​()​ ​throws​ ​IOException​ { 
server ​=​ ​new​ ​NettyServer​(​new​ ​SpecificResponder​(​Mail​.​class​,​new 
MailImpl​()),​ ​new​ ​InetSocketAddress​(​10000​)); 
} 
public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​Exception​ { 
LogUtil​.​println​(​"Starting ServerAvroRPC"​); 
startServer​(); 
LogUtil​.​println​(​"ServerAvroRPC started and wait for 15s"​);  
Thread​.​sleep​(​15000​); 
 
 
server​.​close​(); 
} 
} 
In code of ClientAvroRPC 
public​ ​class​ ​ClientAvroRPC​ { 
    ​public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​IOException​ ​{   
  if​(​args​.​length ​<​ ​3​){ 
  args ​=​ ​new​ ​String​[] 
{​"someone@example.com"​,​"myself@example.com"​,​"Hello !"​}; 
  } 
        ​NettyTransceiver​ client ​=​ ​new​ ​NettyTransceiver​(​new 
InetSocketAddress​(​10000​));   
        ​Mail​ proxy ​=​ ​(​Mail​)​ ​SpecificRequestor​.​getClient​(​Mail​.​class​,​ client​); 
        ​LogUtil​.​println​(​"ClientAvroRPC built OK, got proxy, ready to send data 
..."​);   
        ​Message​ message ​=​ ​new​ ​Message​(); 
        message​.​setTo​(​new​ ​Utf8​(​args​[​0​])); 
        message​.​setFrom​(​new​ ​Utf8​(​args​[​1​])); 
        message​.​setBody​(​new​ ​Utf8​(​args​[​2​])); 
        ​LogUtil​.​println​(​"Calling proxy.send with message:  "​ ​+ 
message​.​toString​()); 
        ​LogUtil​.​println​(​"Result from server: "​ ​+​ proxy​.​send​(​message​));  
        client​.​close​();   
    } 
} 
How it works  
When you start ProxyServerAvroRPC, the socket at port 10000 is listened. 
The client, ClientAvroRPC would send a mail message “Hello !”, which is serialized and 
is sent to ServerAvroRPC via the method send of the instance of Mail class. The output 
when you run the code of ClientAvroRPC is: 
Client​ built​,​ got proxy 
Calling​ proxy​.​send ​with​ message​:​  ​{​"to"​:​ ​"someone@example.com"​,​ ​"from"​: 
"myself@example.com"​,​ ​"body"​:​ ​"Hello !"} 
 
 
Result​:​ ​Sending​ message to someone@example​.​com ​from​ myself@example​.​com ​with​ body 
Hello​ ! 
Recipe 2.11 Building simple HTTP downloader 
Problem: 
Using Netty framework to build a HTTP client, that downloads one specific large file 
from one specific host using one specific URL (https://example.com/a­big­file.zip) over 
HTTP and saves it on disk. 
Getting ready 
Make sure you check out this code at the Git repository of book 
https://github.com/trieu/netty­cookbook 
The full code at the  package netty.cookbook.chapter2.recipe11, class 
HttpDownloader. 
How to do it … 
We will use the method newHttpClientBootstrap of BootstrapTemplate to create new 
bootstrap for a HTTP client, we set the URL with HttpDownloadHandler. 
public​ ​class​ ​HttpDownloader​ { 
public​ ​static​ ​class​ ​HttpDownloadHandler​ ​extends 
SimpleChannelInboundHandler​<​HttpObject​>​ { 
int​ written ​=​ ​0; 
File​ file; 
FileOutputStream​ outStream; 
FileChannel​ fileChnl; 
public​ ​HttpDownloadHandler​(​File​ file​)​ { 
super​(); 
this​.​file ​=​ file; 
} 
void​ initFileChannel​()​ ​throws​ ​FileNotFoundException​ { 
outStream ​=​ ​new​ ​FileOutputStream​(​file​); 
fileChnl ​=​ outStream​.​getChannel​(); 
 
 
} 
void​ writeBytesToFile​(​ByteBuf​ byteBuf​)​ ​throws​ ​IOException​ { 
int​ writtenIndex ​=​ ​0; 
try​ { 
ByteBuffer​ byteBuffer ​=​ byteBuf​.​nioBuffer​(); 
writtenIndex ​+=​ fileChnl​.​write​(​byteBuffer​, 
written​); 
written ​+=​ writtenIndex; 
byteBuf​.​readerIndex​(​byteBuf​.​readerIndex​()​ ​+ 
writtenIndex​); 
fileChnl​.​force​(​false​); 
}​ ​catch​ ​(​Exception​ e​)​ { 
fileChnl​.​close​(); 
outStream​.​close​(); 
} 
} 
@Override 
protected​ ​void​ channelRead0​(​ChannelHandlerContext​ ctx​,​ ​HttpObject 
msg​)​ { 
try​ { 
if​ ​(​msg ​instanceof​ ​HttpRequest​)​ { 
initFileChannel​(); 
}​ ​else​ ​if​ ​(​msg ​instanceof​ ​HttpContent​)​ { 
if​ ​(​fileChnl ​==​ ​null​)​ { 
initFileChannel​(); 
} 
ByteBuf​ byteBuf ​=​ ​((​HttpContent​) 
msg​).​content​(); 
writeBytesToFile​(​byteBuf​); 
}​ ​else​ ​if​ ​(​msg ​instanceof​ ​LastHttpContent​)​ { 
if​ ​(​fileChnl ​!=​ ​null​ ​&&​ outStream ​!=​ ​null​) 
{ 
fileChnl​.​close​(); 
outStream​.​close​(); 
 
 
} 
ctx​.​close​(); 
} 
}​ ​catch​ ​(​IOException​ e​)​ { 
e​.​printStackTrace​(); 
} 
} 
} 
public​ ​static​ ​void​ main​(​String​[]​ args​)​ ​throws​ ​Exception​ { 
String​ url ​=​ ​"http://www.mc2ads.com"; 
File​ file ​=​ ​new​ ​File​(​"./data/www.mc2ads.com.html"​); 
ChannelHandler​ handler ​=​ ​new​ ​HttpDownloadHandler​(​file​); 
BootstrapTemplate​.​newHttpClientBootstrap​(​url​,​ handler​); 
} 
} 
 
 

Weitere ähnliche Inhalte

Was ist angesagt?

Inside neutron 2
Inside neutron 2Inside neutron 2
Inside neutron 2
Robin Gong
 
Openstack Neutron and SDN
Openstack Neutron and SDNOpenstack Neutron and SDN
Openstack Neutron and SDN
inakipascual
 
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
Dave Neary
 
OpenStack Neutron Liberty Updates
OpenStack Neutron Liberty UpdatesOpenStack Neutron Liberty Updates
OpenStack Neutron Liberty Updates
mestery
 

Was ist angesagt? (20)

How to build a Neutron Plugin (stadium edition)
How to build a Neutron Plugin (stadium edition)How to build a Neutron Plugin (stadium edition)
How to build a Neutron Plugin (stadium edition)
 
Quantum (OpenStack Meetup Feb 9th, 2012)
Quantum (OpenStack Meetup Feb 9th, 2012)Quantum (OpenStack Meetup Feb 9th, 2012)
Quantum (OpenStack Meetup Feb 9th, 2012)
 
Building scalable network applications with Netty (as presented on NLJUG JFal...
Building scalable network applications with Netty (as presented on NLJUG JFal...Building scalable network applications with Netty (as presented on NLJUG JFal...
Building scalable network applications with Netty (as presented on NLJUG JFal...
 
Inside neutron 2
Inside neutron 2Inside neutron 2
Inside neutron 2
 
Openstack Neutron and SDN
Openstack Neutron and SDNOpenstack Neutron and SDN
Openstack Neutron and SDN
 
WebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST MicroserviceWebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST Microservice
 
Software Defined Networking: The OpenDaylight Project
Software Defined Networking: The OpenDaylight ProjectSoftware Defined Networking: The OpenDaylight Project
Software Defined Networking: The OpenDaylight Project
 
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
Networking in OpenStack for non-networking people: Neutron, Open vSwitch and ...
 
Overlay/Underlay - Betting on Container Networking
Overlay/Underlay - Betting on Container NetworkingOverlay/Underlay - Betting on Container Networking
Overlay/Underlay - Betting on Container Networking
 
Overview of Distributed Virtual Router (DVR) in Openstack/Neutron
Overview of Distributed Virtual Router (DVR) in Openstack/NeutronOverview of Distributed Virtual Router (DVR) in Openstack/Neutron
Overview of Distributed Virtual Router (DVR) in Openstack/Neutron
 
Reactive Java: Promises and Streams with Reakt (JavaOne talk 2016)
Reactive Java: Promises and Streams with Reakt  (JavaOne talk 2016)Reactive Java: Promises and Streams with Reakt  (JavaOne talk 2016)
Reactive Java: Promises and Streams with Reakt (JavaOne talk 2016)
 
OpenStack networking - Neutron deep dive with PLUMgrid
OpenStack networking - Neutron deep dive with PLUMgridOpenStack networking - Neutron deep dive with PLUMgrid
OpenStack networking - Neutron deep dive with PLUMgrid
 
Securing & Enforcing Network Policy and Encryption with Weave Net
Securing & Enforcing Network Policy and Encryption with Weave NetSecuring & Enforcing Network Policy and Encryption with Weave Net
Securing & Enforcing Network Policy and Encryption with Weave Net
 
OpenStack Neutron Liberty Updates
OpenStack Neutron Liberty UpdatesOpenStack Neutron Liberty Updates
OpenStack Neutron Liberty Updates
 
Neutron behind the scenes
Neutron   behind the scenesNeutron   behind the scenes
Neutron behind the scenes
 
Neutron high availability open stack architecture openstack israel event 2015
Neutron high availability  open stack architecture   openstack israel event 2015Neutron high availability  open stack architecture   openstack israel event 2015
Neutron high availability open stack architecture openstack israel event 2015
 
OpenStack Neutron's Distributed Virtual Router
OpenStack Neutron's Distributed Virtual RouterOpenStack Neutron's Distributed Virtual Router
OpenStack Neutron's Distributed Virtual Router
 
Coap based application for android phones
Coap based application for android phonesCoap based application for android phones
Coap based application for android phones
 
OpenStack Neutron new developers on boarding
OpenStack Neutron new developers on boardingOpenStack Neutron new developers on boarding
OpenStack Neutron new developers on boarding
 
Introduction to Software Defined Networking and OpenStack Neutron
Introduction to Software Defined Networking and OpenStack NeutronIntroduction to Software Defined Networking and OpenStack Neutron
Introduction to Software Defined Networking and OpenStack Neutron
 

Andere mochten auch

Where is my next jobs in the age of Big Data and Automation
Where is my next jobs in the age of Big Data and AutomationWhere is my next jobs in the age of Big Data and Automation
Where is my next jobs in the age of Big Data and Automation
Trieu Nguyen
 
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
Dawen Liang
 

Andere mochten auch (19)

Using SCTP with Scamper and Netty
Using SCTP with Scamper and NettyUsing SCTP with Scamper and Netty
Using SCTP with Scamper and Netty
 
Ambry : Linkedin's Scalable Geo-Distributed Object Store
Ambry : Linkedin's Scalable Geo-Distributed Object StoreAmbry : Linkedin's Scalable Geo-Distributed Object Store
Ambry : Linkedin's Scalable Geo-Distributed Object Store
 
【Potatotips #26】Replace EventBus with RxJava/RxAndroid
【Potatotips #26】Replace EventBus with RxJava/RxAndroid【Potatotips #26】Replace EventBus with RxJava/RxAndroid
【Potatotips #26】Replace EventBus with RxJava/RxAndroid
 
Asynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with NettyAsynchronous, Event-driven Network Application Development with Netty
Asynchronous, Event-driven Network Application Development with Netty
 
Fast Data processing with RFX
Fast Data processing with RFXFast Data processing with RFX
Fast Data processing with RFX
 
Slide 2 collecting, storing and analyzing big data
Slide 2 collecting, storing and analyzing big dataSlide 2 collecting, storing and analyzing big data
Slide 2 collecting, storing and analyzing big data
 
Reactive Data System in Practice
Reactive Data System in PracticeReactive Data System in Practice
Reactive Data System in Practice
 
Where is my next jobs in the age of Big Data and Automation
Where is my next jobs in the age of Big Data and AutomationWhere is my next jobs in the age of Big Data and Automation
Where is my next jobs in the age of Big Data and Automation
 
2016 Data Science Salary Survey
2016 Data Science Salary Survey2016 Data Science Salary Survey
2016 Data Science Salary Survey
 
Slide 3 Fast Data processing with kafka, rfx and redis
Slide 3 Fast Data processing with kafka, rfx and redisSlide 3 Fast Data processing with kafka, rfx and redis
Slide 3 Fast Data processing with kafka, rfx and redis
 
Experience economy
Experience economyExperience economy
Experience economy
 
Introduction to Human Data Theory for Digital Economy
Introduction to Human Data Theory for Digital EconomyIntroduction to Human Data Theory for Digital Economy
Introduction to Human Data Theory for Digital Economy
 
How to build a data driven business in big data age
How to build a data driven business in big data ageHow to build a data driven business in big data age
How to build a data driven business in big data age
 
TỔNG QUAN VỀ DỮ LIỆU LỚN (BIGDATA)
TỔNG QUAN VỀ DỮ LIỆU LỚN (BIGDATA)TỔNG QUAN VỀ DỮ LIỆU LỚN (BIGDATA)
TỔNG QUAN VỀ DỮ LIỆU LỚN (BIGDATA)
 
Past, Present & Future of Recommender Systems: An Industry Perspective
Past, Present & Future of Recommender Systems: An Industry PerspectivePast, Present & Future of Recommender Systems: An Industry Perspective
Past, Present & Future of Recommender Systems: An Industry Perspective
 
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
Factorization Meets the Item Embedding: Regularizing Matrix Factorization wit...
 
(Some) pitfalls of distributed learning
(Some) pitfalls of distributed learning(Some) pitfalls of distributed learning
(Some) pitfalls of distributed learning
 
Balancing Discovery and Continuation in Recommendations
Balancing Discovery and Continuation in RecommendationsBalancing Discovery and Continuation in Recommendations
Balancing Discovery and Continuation in Recommendations
 
Building Netty Servers
Building Netty ServersBuilding Netty Servers
Building Netty Servers
 

Ähnlich wie Netty Cookbook - Chapter 2

Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
Đồng Quốc Vương
 
Nachos Theoretical assigment 3
Nachos Theoretical assigment 3Nachos Theoretical assigment 3
Nachos Theoretical assigment 3
colli03
 
Microsoft Offical Course 20410C_05
Microsoft Offical Course 20410C_05Microsoft Offical Course 20410C_05
Microsoft Offical Course 20410C_05
gameaxt
 
NWI FOR OLATUNDE ISMAILA (G10B)
NWI FOR OLATUNDE ISMAILA (G10B)NWI FOR OLATUNDE ISMAILA (G10B)
NWI FOR OLATUNDE ISMAILA (G10B)
olatunde ismaila
 

Ähnlich wie Netty Cookbook - Chapter 2 (20)

Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
Www ccnav5 net_ccna_1_chapter_3_v5_0_exam_answers_2014
 
maXbox_Arduino_Pascal_Magazine
maXbox_Arduino_Pascal_MagazinemaXbox_Arduino_Pascal_Magazine
maXbox_Arduino_Pascal_Magazine
 
Ccna guide
Ccna guideCcna guide
Ccna guide
 
Monkey Server
Monkey ServerMonkey Server
Monkey Server
 
Maxbox starter18
Maxbox starter18Maxbox starter18
Maxbox starter18
 
Client server
Client serverClient server
Client server
 
Hackerworkshop exercises
Hackerworkshop exercisesHackerworkshop exercises
Hackerworkshop exercises
 
An introduction to workflow-based programming with Node-RED
An introduction to workflow-based programming with Node-REDAn introduction to workflow-based programming with Node-RED
An introduction to workflow-based programming with Node-RED
 
javanetworking
javanetworkingjavanetworking
javanetworking
 
maXbox Arduino Tutorial
maXbox Arduino TutorialmaXbox Arduino Tutorial
maXbox Arduino Tutorial
 
Practical Guide to Run an IEEE 802.15.4 Network with 6LoWPAN Under Linux
Practical Guide to Run an IEEE 802.15.4 Network with 6LoWPAN Under LinuxPractical Guide to Run an IEEE 802.15.4 Network with 6LoWPAN Under Linux
Practical Guide to Run an IEEE 802.15.4 Network with 6LoWPAN Under Linux
 
Network Programming-Python-13-8-2023.pptx
Network Programming-Python-13-8-2023.pptxNetwork Programming-Python-13-8-2023.pptx
Network Programming-Python-13-8-2023.pptx
 
Cloud Presentation.pdf
Cloud Presentation.pdfCloud Presentation.pdf
Cloud Presentation.pdf
 
Nachos Theoretical assigment 3
Nachos Theoretical assigment 3Nachos Theoretical assigment 3
Nachos Theoretical assigment 3
 
Midokura Gluecon 2014 - Level up your OpenStack Neutron Networking
Midokura Gluecon 2014 - Level up your OpenStack Neutron NetworkingMidokura Gluecon 2014 - Level up your OpenStack Neutron Networking
Midokura Gluecon 2014 - Level up your OpenStack Neutron Networking
 
.NET Core Today and Tomorrow
.NET Core Today and Tomorrow.NET Core Today and Tomorrow
.NET Core Today and Tomorrow
 
Microsoft Offical Course 20410C_05
Microsoft Offical Course 20410C_05Microsoft Offical Course 20410C_05
Microsoft Offical Course 20410C_05
 
NWI FOR OLATUNDE ISMAILA (G10B)
NWI FOR OLATUNDE ISMAILA (G10B)NWI FOR OLATUNDE ISMAILA (G10B)
NWI FOR OLATUNDE ISMAILA (G10B)
 
CCNA4 Verson6 Chapter2
CCNA4 Verson6 Chapter2CCNA4 Verson6 Chapter2
CCNA4 Verson6 Chapter2
 
WebRTC Seminar Report
WebRTC  Seminar ReportWebRTC  Seminar Report
WebRTC Seminar Report
 

Mehr von Trieu Nguyen

[Notes] Customer 360 Analytics with LEO CDP
[Notes] Customer 360 Analytics with LEO CDP[Notes] Customer 360 Analytics with LEO CDP
[Notes] Customer 360 Analytics with LEO CDP
Trieu Nguyen
 

Mehr von Trieu Nguyen (20)

Building Your Customer Data Platform with LEO CDP in Travel Industry.pdf
Building Your Customer Data Platform with LEO CDP in Travel Industry.pdfBuilding Your Customer Data Platform with LEO CDP in Travel Industry.pdf
Building Your Customer Data Platform with LEO CDP in Travel Industry.pdf
 
Building Your Customer Data Platform with LEO CDP - Spa and Hotel Business
Building Your Customer Data Platform with LEO CDP - Spa and Hotel BusinessBuilding Your Customer Data Platform with LEO CDP - Spa and Hotel Business
Building Your Customer Data Platform with LEO CDP - Spa and Hotel Business
 
Building Your Customer Data Platform with LEO CDP
Building Your Customer Data Platform with LEO CDP Building Your Customer Data Platform with LEO CDP
Building Your Customer Data Platform with LEO CDP
 
How to track and improve Customer Experience with LEO CDP
How to track and improve Customer Experience with LEO CDPHow to track and improve Customer Experience with LEO CDP
How to track and improve Customer Experience with LEO CDP
 
[Notes] Customer 360 Analytics with LEO CDP
[Notes] Customer 360 Analytics with LEO CDP[Notes] Customer 360 Analytics with LEO CDP
[Notes] Customer 360 Analytics with LEO CDP
 
Leo CDP - Pitch Deck
Leo CDP - Pitch DeckLeo CDP - Pitch Deck
Leo CDP - Pitch Deck
 
LEO CDP - What's new in 2022
LEO CDP  - What's new in 2022LEO CDP  - What's new in 2022
LEO CDP - What's new in 2022
 
Lộ trình triển khai LEO CDP cho ngành bất động sản
Lộ trình triển khai LEO CDP cho ngành bất động sảnLộ trình triển khai LEO CDP cho ngành bất động sản
Lộ trình triển khai LEO CDP cho ngành bất động sản
 
Why is LEO CDP important for digital business ?
Why is LEO CDP important for digital business ?Why is LEO CDP important for digital business ?
Why is LEO CDP important for digital business ?
 
From Dataism to Customer Data Platform
From Dataism to Customer Data PlatformFrom Dataism to Customer Data Platform
From Dataism to Customer Data Platform
 
Data collection, processing & organization with USPA framework
Data collection, processing & organization with USPA frameworkData collection, processing & organization with USPA framework
Data collection, processing & organization with USPA framework
 
Part 1: Introduction to digital marketing technology
Part 1: Introduction to digital marketing technologyPart 1: Introduction to digital marketing technology
Part 1: Introduction to digital marketing technology
 
Why is Customer Data Platform (CDP) ?
Why is Customer Data Platform (CDP) ?Why is Customer Data Platform (CDP) ?
Why is Customer Data Platform (CDP) ?
 
How to build a Personalized News Recommendation Platform
How to build a Personalized News Recommendation PlatformHow to build a Personalized News Recommendation Platform
How to build a Personalized News Recommendation Platform
 
How to grow your business in the age of digital marketing 4.0
How to grow your business  in the age of digital marketing 4.0How to grow your business  in the age of digital marketing 4.0
How to grow your business in the age of digital marketing 4.0
 
Video Ecosystem and some ideas about video big data
Video Ecosystem and some ideas about video big dataVideo Ecosystem and some ideas about video big data
Video Ecosystem and some ideas about video big data
 
Concepts, use cases and principles to build big data systems (1)
Concepts, use cases and principles to build big data systems (1)Concepts, use cases and principles to build big data systems (1)
Concepts, use cases and principles to build big data systems (1)
 
Open OTT - Video Content Platform
Open OTT - Video Content PlatformOpen OTT - Video Content Platform
Open OTT - Video Content Platform
 
Apache Hadoop and Spark: Introduction and Use Cases for Data Analysis
Apache Hadoop and Spark: Introduction and Use Cases for Data AnalysisApache Hadoop and Spark: Introduction and Use Cases for Data Analysis
Apache Hadoop and Spark: Introduction and Use Cases for Data Analysis
 
Introduction to Recommendation Systems (Vietnam Web Submit)
Introduction to Recommendation Systems (Vietnam Web Submit)Introduction to Recommendation Systems (Vietnam Web Submit)
Introduction to Recommendation Systems (Vietnam Web Submit)
 

Kürzlich hochgeladen

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Netty Cookbook - Chapter 2