在实际的项目中应该如何使用netty去通信呢?

一般来说,会有以下三种情况,

1长连接 也就是服务器和客户端的通道一直不关闭,如果服务器性能非常好,并且在客户端数量不是很多的情况下,可以选择使用这种方式。

2短连接  一次性批量提交数据,我们可能会吧我们的数据保存在数据库中,比如1个小时提交提交一次。这种做法的弊端是不能够实时传输,实时性要求不高的情况可以推荐使用

3一种特殊的长连接 在特定时间的内,如果服务器和客服端没有通讯 就断开连接 下次当客户端需要再次发送数据的时候,再次连接 。但是这种方式我们需要考虑?

1连接超时以后我们如何断开连接? 而在需要发送数据的时候我们怎么再次连接?

2服务器宕机了怎么办?

1连接超时以后我们如何断开连接?(在netty中可以通过ReadTimeoutHandler类实现超过多长时间断开连接)

而在需要发送数据的时候我们怎么再次连接?

(我们可以封装一个方法 调用该方法就可以获得连接)

2服务器宕机了怎么办?

生产环境我们一般会部署netty集群,结合zookeeper完成。

下面我用代码演示一下

Server端口变化不大 ,主要是客户端

Server端代码

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler; public class Server {
public static void main(String[] args) throws Exception {
//
EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap bootStrap = new ServerBootstrap(); bootStrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel sc) throws Exception {
// ByteBuf delimiters = Unpooled.copiedBuffer("$".getBytes()) ;
// sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiters ));
// sc.pipeline().addLast(new StringDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
sc.pipeline().addLast(new ReadTimeoutHandler(5));//超时时间设置
sc.pipeline().addLast(new ServerHandler());
}
});
ChannelFuture f = bootStrap.bind(8888).sync();
ChannelFuture f1 = bootStrap.bind(9999).sync();
//服务器一直不关闭
f.channel().closeFuture().sync();
f1.channel().closeFuture().sync();
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
} }

  

import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class ServerHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("server " + msg);
Data data = new Data();
data.setId(1);
data.setName("server replay");
// 写操作完成以后就断开连接
ctx.writeAndFlush(data).addListener(ChannelFutureListener.CLOSE); } @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} }

  序列化工具代码 这里使用jboss的Marshalling

import io.netty.handler.codec.marshalling.DefaultMarshallerProvider;
import io.netty.handler.codec.marshalling.DefaultUnmarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallingDecoder;
import io.netty.handler.codec.marshalling.MarshallingEncoder;
import io.netty.handler.codec.marshalling.UnmarshallerProvider; import org.jboss.marshalling.MarshallerFactory;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.MarshallingConfiguration; public final class MarshallingCodeCFactory { public static MarshallingDecoder buildMarshallingDecoder() {
//首先通过Marshalling工具类的精通方法获取Marshalling实例对象 参数serial标识创建的是java序列化工厂对象。
final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
//创建了MarshallingConfiguration对象,配置了版本号为5
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
//根据marshallerFactory和configuration创建provider
UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
//构建Netty的MarshallingDecoder对象,俩个参数分别为provider和单个消息序列化后的最大长度
MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024);
return decoder;
} public static MarshallingEncoder buildMarshallingEncoder() {
final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
final MarshallingConfiguration configuration = new MarshallingConfiguration();
configuration.setVersion(5);
MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
//构建Netty的MarshallingEncoder对象,MarshallingEncoder用于实现序列化接口的POJO对象序列化为二进制数组
MarshallingEncoder encoder = new MarshallingEncoder(provider);
return encoder;
}
}

  ================

一个简单的实体类 (Data)

import java.io.Serializable;

public class Data implements Serializable{
/**
*
*/
private static final long serialVersionUID = -963211196207628767L;
private Integer id;
private String name; @Override
public String toString() {
return " [id=" + id + ", name=" + name + "]";
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

  ==================================================================================================

以下是客户端代码

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler; public class Client {
EventLoopGroup workGroup = null;
Bootstrap bootstrap = null;
ChannelFuture channelFuture = null; private static class ClientFactory {
private static Client instance = new Client();
} public static Client getClientInstance() {
return ClientFactory.instance;
} private Client() {
// 数理化相关对象
workGroup = new NioEventLoopGroup();
bootstrap = new Bootstrap();
bootstrap.group(workGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() { @Override
protected void initChannel(SocketChannel sc) throws Exception {
// ByteBuf delimiters = Unpooled.copiedBuffer("$".getBytes()) ;
// sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,
// delimiters ));
// sc.pipeline().addLast(new StringDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
sc.pipeline().addLast(new ReadTimeoutHandler(5));
sc.pipeline().addLast(new ClientHandler());
}
});
} public void connect() {
try {
this.channelFuture = bootstrap.connect("127.0.0.1", 9999).sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } public ChannelFuture getChannelFuture() {
if (this.channelFuture == null) {
this.connect();
}
if (!this.channelFuture.channel().isActive()) {
this.connect();
}
return this.channelFuture;
} public static void main(String[] args) throws Exception { final Client client = getClientInstance();
client.connect();
ChannelFuture cf = client.getChannelFuture();
Data data = new Data();
data.setId(1);
data.setName("first");
cf.channel().writeAndFlush(data);
Thread.sleep(6000);
//因为设置的5秒超时 这里通过一个子线程 模拟再次连接
new Thread(new Runnable() {
public void run() {
System.out.println("进入子线程...");
ChannelFuture cf = client.getChannelFuture();
Data data = new Data();
data.setId(2);
data.setName("second");
cf.channel().writeAndFlush(data);
try {
cf.channel().closeFuture().sync();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("子线程结束!!");
}
}).start();
cf.channel().closeFuture().sync(); System.out.println("主线程结束!!");
}
}

  

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter { /**
* 通道刚刚建立的时候 发送认证消息 (认证通过 建立连接 失败 关闭连接)
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
// ctx.channel().writeAndFlush("发送认证消息");
super.channelActive(ctx);
} @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
System.out.println("Client: " + (Data)msg);
} finally {
ReferenceCountUtil.release(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}

  一下是运行结果

服务器端

客户端

netty2 案例:数据通信的更多相关文章

  1. Netty 编解码技术 数据通信和心跳监控案例

    Netty 编解码技术 数据通信和心跳监控案例 多台服务器之间在进行跨进程服务调用时,需要使用特定的编解码技术,对需要进行网络传输的对象做编码和解码操作,以便完成远程调用.Netty提供了完善,易扩展 ...

  2. 使用hessian+protocol buffer+easyUI综合案例--登陆

    首先先简单介绍下hessian ,protocol buffer, easyUI框架 hessian: Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协 ...

  3. 第二篇:智能电网(Smart Grid)中的数据工程与大数据案例分析

    前言 上篇文章中讲到,在智能电网的控制与管理侧中,数据的分析和挖掘.可视化等工作属于核心环节.除此之外,二次侧中需要对数据进行采集,数据共享平台的搭建显然也涉及到数据的管理.那么在智能电网领域中,数据 ...

  4. TCP/IP协议原理与应用笔记09:数据通信---封装

    2016-08-091. 数据通信----封装: 2. 协议数据单元: PDU:对等层数据通信的单元. 比如Source端的应用层 和 Destination端的应用层是对等层(L7),这个时候L7 ...

  5. 《深入理解Java虚拟机》-----第5章 jvm调优案例分析与实战

    案例分析 高性能硬件上的程序部署策略 例 如 ,一个15万PV/天左右的在线文档类型网站最近更换了硬件系统,新的硬件为4个CPU.16GB物理内存,操作系统为64位CentOS 5.4 , Resin ...

  6. 5、JVM--调优案例分析

    5.1.案例分析 5.1.1.高性能硬件上的程序部署策略 假如一个15w/天左右的在线文档类型网站再准备更换硬件系统 新的硬件为4个CPU.16GB物理内存,操作系统为64为Cento是 Resin作 ...

  7. vue02—— 动画、组件、组件之间的数据通信

    一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...

  8. Java之JVM调优案例分析与实战(2) - 集群间同步导致的内存溢出

    环境:一个基于B/S的MIS系统,硬件为两台2个CPU.8GB内存的HP小型机,服务器是WebLogic 9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群. 说明:由于是亲 ...

  9. KVM部署LVS集群故障案例一则

    一.故障现象 KVM部署LVS(Linux Virtual Server)集群后,能够单独以HTTP方式访问RS(Real Server)的实际IP,但无法通过VIP(Virtual IP)访问. 二 ...

随机推荐

  1. mosquitto centos安装配置

    周末弄wordpress的Mysql,一不小心把wordpress弄不好了,写了的好几遍文章也没有了,一怒之下,把整个系统重装了,安装了不带任何软件的新系统,重新搭一遍. 0.安装ftp服务器 #yu ...

  2. [转]检测到有潜在危险的 Request.Form 值

    <system.web> <httpRuntime targetFramework="4.0" requestValidationMode="2.0&q ...

  3. 6.3.4 新的_Bool类型

    如果把其他非零数值赋给_Bool类型的变量,该变量会被设置为1.这反映了C把所有的非零值都视为真. input_is_good = (scanf("%ld", &num) ...

  4. 刘志梅201771010115.《面向对象程序设计(java)》第六周学习总结

    实验六 继承定义与使用 实验时间 2018-9-28 1.实验目的与要求 (1) 继承的定义:用已有类来构建新类的一种机制.当定义了一个新类继承了一个类时,这个新类就继承了这个类的方法和域,同时在新类 ...

  5. Phpstorm 与 服务器 同步 代码

    链接:(自己领悟就好了) Phpstorm同步代码

  6. Java 详解 JVM 工作原理和流程

    Java 详解 JVM 工作原理和流程 作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java ...

  7. Redis 主从集群搭建及哨兵模式配置

    最近搭建了redis集群及哨兵模式,为方便以后查看特此记录下来: 1.Redis安装 2.主从架构 2.1 Redis主从架构图 2.2Redis主从结构搭建 Redis集群不用安装多个Redis,只 ...

  8. java.lang.NoClassDefFoundError: org/apache/tomcat/util/res/StringManager

    一个比较老的web项目,  IDEA 导入后不能用,  出现了各种问题, 但是, 别人用eclipse 导入就不会有问题,  我折腾了半天, 还是各种问题,  真是郁闷了.  哎, 承认很难配置吧, ...

  9. Android应用开发中,第三方集成新浪微博(sinaWeiboSDK)的过程记录

    作为一个android开发人员,不可避免的要学会使用和集成第三方API的能力 而新浪微博作为现在最主要的新闻速递媒体,使用十分普遍,并且提供了较为详细的API接入方法,故此选择集成sinaWeibiS ...

  10. ConcurrentModificationException并发修改异常

    //创建集合对象 Collection c = new ArrayList(); c.add("hello"); c.add("world"); c.add(& ...