相关知识点:
[1] ChannelGroup是一个容纳打开的通道实例的线程安全的集合,方便我们统一施加操作。所以在使用的过程中能够将一些相关的Channel归类为一个有意义的集合。关闭的通道会自己主动从集合中移除。并且一个Channel能够属于多个ChannelGroup。常见的应用场景是 向一组通道广播消息;简化一组通道的关闭流程。

[2] 由于在Channel中流通的是ChannelBuffer (能够联系NIO ByteBuffer进行理解)。而在内部流水线中处理的可能是一个个对象,所以在收到或要发送到对端的时候就须要一个解码,编码的过程:在实际有意义的对象和字节数组间转换。
[3] 在client和服务器端流水线中handler运行顺序是不同的。在client中运行顺序和ChannelPipeline的添加顺序一致。而服务器端则恰好是相反的,这一点要注意,所以看到编解码类的位置是那样的。
详细代码:
TimeClient.java
import java.net.InetSocketAddress;
import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture;
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.NioClientSocketChannelFactory; public class TimeClient {
public static void main(String[] args) {
String host = "localhost";
int port = 8080; if(args.length == 2){
host = args[0];
port = Integer.parseInt(args[1]);
} ChannelFactory factory = new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ClientBootstrap bootstrap = new ClientBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new TimeDecoder2(),
new TimeClientHandler4());
}
}); ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); //
future.awaitUninterruptibly();
if(!future.isSuccess()){
future.getCause().printStackTrace();
}
future.getChannel().getCloseFuture().awaitUninterruptibly();
factory.releaseExternalResources();
} }

TimeDecoder2.java

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder; public class TimeDecoder2 extends FrameDecoder{ @Override
protected Object decode(ChannelHandlerContext ctx, Channel channel,
ChannelBuffer buffer) throws Exception {
if(buffer.readableBytes() < 4)
return null;
return new UnixTime(buffer.readInt());
}
}

TimeClientHandler4.java

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
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 TimeClientHandler4 extends SimpleChannelHandler{
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
//the decoder put UnixTime obj,so get just what we need
UnixTime cur = (UnixTime)e.getMessage();
System.out.println(cur);
e.getChannel().close();
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
e.getCause().printStackTrace();
Channel c = e.getChannel();
c.close();
}
}

TimeServer.java

import java.net.InetSocketAddress;
import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
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.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; public class TimeServer {
//[1]
public static ChannelGroup allChannels = new DefaultChannelGroup("time-server"); public static void main(String[] args) {
ChannelFactory factory = new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()); ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new TimeServerHandler2(),
new TimeEncoder());
}
}); bootstrap.setOption("reuseAddr", true);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true); Channel channel = bootstrap.bind(new InetSocketAddress(8080)); allChannels.add(channel);
//waitForShutdownCommand(); this is a imaginary logic:for instance
//when there is accepted connection we close this server ;
if(allChannels.size() >=2){
ChannelGroupFuture f = allChannels.close();
f.awaitUninterruptibly();
factory.releaseExternalResources();
}
}
}

TimeServerHandler2.java

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler; public class TimeServerHandler2 extends SimpleChannelHandler{
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
TimeServer.allChannels.add(e.getChannel());
}
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
UnixTime time = new UnixTime((int) (System.currentTimeMillis() / 1000));
ChannelFuture f = e.getChannel().write(time);
f.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
e.getCause().printStackTrace();
Channel c = e.getChannel();
c.close();
}
}

TimeEncoder.java

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler; public class TimeEncoder extends SimpleChannelHandler{
@Override
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
UnixTime time = (UnixTime)e.getMessage();
ChannelBuffer buf = ChannelBuffers.buffer(4);
buf.writeInt(time.getValue());
Channels.write(ctx, e.getFuture(), buf);
}
}

UnixTime.java

import java.util.Date;

public class UnixTime {
private int value;
public UnixTime(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
public void setValue(int value){
this.value = value;
}
@Override
public String toString() {
//Allocates a Date object and initializes it to represent the specified number
//of milliseconds since the standard base time known as "the epoch",
//namely January 1, 1970, 00:00:00 GMT
return new Date(value * 1000L).toString();
}
}

Netty实现时间服务演示样例的更多相关文章

  1. 一步一步跟我学习lucene(18)---lucene索引时join和查询时join使用演示样例

    了解sql的朋友都知道,我们在查询的时候能够採用join查询,即对有一定关联关系的对象进行联合查询来对多维的数据进行整理.这个联合查询的方式挺方便的.跟我们现实生活中的托人找关系类似,我们想要完毕一件 ...

  2. JDBC连接MySQL数据库及演示样例

    JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  3. java 覆盖hashCode()深入探讨 代码演示样例

    java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...

  4. 模式识别 - 处理多演示样例学习(MIL)特征(matlab)

    处理多演示样例学习(MIL)特征(matlab) 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27206325 多演示样例学习( ...

  5. java并行调度框架封装及演示样例

    參考资料:  阿里巴巴开源项目 CobarClient  源代码实现. 分享作者:闫建忠 分享时间:2014年5月7日 ---------------------------------------- ...

  6. Java连接redis的使用演示样例

    Java连接redis的使用演示样例 Redis是开源的key-value存储工具,redis通经常使用来存储结构化的数据,由于redis的key能够包括String.hash.listset和sor ...

  7. Introspector(内省)简单演示样例 与 简单应用

    简单演示样例: package com.asdfLeftHand.test; import java.beans.BeanDescriptor; import java.beans.BeanInfo; ...

  8. libcurl使用演示样例

    简要说明:C++使用libcurl訪问"www.baidu.com".获取返回码和打印出http文件 /* * @ libcurl使用演示样例 * @ 2014.04.29 * @ ...

  9. 构造Scala开发环境并创建ApiDemos演示样例项目

    从2011年開始写Android ApiDemos 以来.Android的版本号也更新了非常多,眼下的版本号已经是4.04. ApiDemos中的样例也添加了不少,有必要更新Android ApiDe ...

随机推荐

  1. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  2. Python 可变对象与不可变对象

    1. 不可变(immutable):int.字符串(string).float.(数值型number).元组(tuple) 可变(mutable):字典型(dictionary).列表型(list) ...

  3. 测试开发系列之Python开发mock接口(三)

    于进入主题了,前面的准备工作都已经做好了,下面就开始写逻辑的代码了,代码我已经写好了,每行都加了注释,不明白的可以留言.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...

  4. mysql workbench 导出建表语句

    导出建表语句和数据 server—–>data export—–>选中表  注意,export to dump project folder,这种方式是每个表对应一个sql文件.  导出建 ...

  5. 八皇后问题Python实现

    八皇后问题描述 问题: 国际象棋棋盘是8 * 8的方格,每个方格里放一个棋子.皇后这种棋子可以攻击同一行或者同一列或者斜线(左上左下右上右下四个方向)上的棋子.在一个棋盘上如果要放八个皇后,使得她们互 ...

  6. luogu P1342 请柬

    题目描述 在电视时代,没有多少人观看戏剧表演.Malidinesia古董喜剧演员意识到这一事实,他们想宣传剧院,尤其是古色古香的喜剧片.他们已经打印请帖和所有必要的信息和计划.许多学生被雇来分发这些请 ...

  7. All you need to know about SYN floods

    http://blog.dubbelboer.com/ Date: 09 Apr 2012Author: Erik Dubbelboer SYN cookies So one day I notice ...

  8. IOS -- base64编码

    在iOS7以后可以用NSData自带的base64EncodedStringWithOptions进行编解码: 方法如下: - (NSString *)encodeToBase64String:(UI ...

  9. 基于Lua插件化的Pcap流量监听代理

    1.前言 我们在实际工作中,遇到了一个这样的用例,在每天例行扫描活动中,发现有些应用系统不定期的被扫挂,因为我们不是服务的制造者,没有办法在不同的系统里打印日志,所以我们就想用一个工具来获取特定服务的 ...

  10. 数据库系统学习(十)-嵌入式SQL语言之动态SQL

    第十讲 嵌入式SQL语言之动态SQL 静态SQL 区别变量和属性:高级语言向嵌入式SQL传递变量的方法 动态SQL 动态构造SQL语句是应用程序员必须掌握的重要手段 SQL语句的动态构造示例 根据界面 ...