Netty学习教程之Netty与Marshalling结合发送对象

前言

之前的一篇文章是Netty简单的学习,我们可以传递一个字符串,那么如果我们想要在Netty中传递一个对象该怎么办呢 ?

那么这个时候我们可以结合Marshalling来传递。

方法如下:

首先需要导入两个Marshalling的依赖包

jboss-marshalling-1.3.0.CR9.jar
jboss-marshalling-serial-1.3.0.CR9.jar

注意:我开始学习的时候只导入了第一个jar包,没有导入第二个,结果是不报错,但是客户端和服务端之间传递不了消息。所以两个包一定要都导入才行。

MarshallingCodeCFactory工具类

public class MarshallingCodeCFactory { 

 public static MarshallingDecoder buildMarshallingDecoder() {
  final MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory("serial");
  final MarshallingConfiguration configuration = new MarshallingConfiguration();
  configuration.setVersion(5);
  UnmarshallerProvider provider = new DefaultUnmarshallerProvider(factory, configuration);
  MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024*1024);
  return decoder;
 } 

 public static MarshallingEncoder buildMarshallingEncoder() {
  final MarshallerFactory factory = Marshalling.getProvidedMarshallerFactory("serial");
  final MarshallingConfiguration configuration = new MarshallingConfiguration();
  configuration.setVersion(5);
  MarshallerProvider provider = new DefaultMarshallerProvider(factory, configuration);
  MarshallingEncoder encoder = new MarshallingEncoder(provider);
  return encoder;
 }
} 

server端

public class Server { 

 public static void main(String[] args) throws InterruptedException {
  //1.第一个线程组是用于接收Client端连接的
  EventLoopGroup bossGroup = new NioEventLoopGroup();
  //2.第二个线程组是用于实际的业务处理的
  EventLoopGroup workerGroup = new NioEventLoopGroup();
  ServerBootstrap b = new ServerBootstrap();
  b.group(bossGroup, workerGroup);//绑定两个线程池
  b.channel(NioServerSocketChannel.class);//指定NIO的模式,如果是客户端就是NioSocketChannel
  b.option(ChannelOption.SO_BACKLOG, 1024);//TCP的缓冲区设置
  b.option(ChannelOption.SO_SNDBUF, 32*1024);//设置发送缓冲的大小
  b.option(ChannelOption.SO_RCVBUF, 32*1024);//设置接收缓冲区大小
  b.option(ChannelOption.SO_KEEPALIVE, true);//保持连续
  b.childHandler(new ChannelInitializer<SocketChannel>() {
   protected void initChannel(SocketChannel ch) throws Exception {
    //设置Marshalling的编码和解码
    ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
    ch.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
    ch.pipeline().addLast(new ServertHandler());
   }
  });
  ChannelFuture future = b.bind(8765).sync();//绑定端口
  future.channel().closeFuture().sync();//等待关闭(程序阻塞在这里等待客户端请求)
  bossGroup.shutdownGracefully();//关闭线程
  workerGroup.shutdownGracefully();//关闭线程
 } 

} 

ServerHandler处理类

public class ServertHandler extends ChannelHandlerAdapter { 

 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
   throws Exception {
  cause.printStackTrace();
 } 

 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg)
   throws Exception {
  Send send = (Send) msg;
  System.out.println("client发送:"+send); 

  Receive receive = new Receive();
  receive.setId(send.getId());
  receive.setMessage(send.getMessage());
  receive.setName(send.getName());
  ctx.writeAndFlush(receive);
 } 

} 

由于我们已经在Server端和Client端定义了传递的类型又Marshalling工厂处理,所以此时我们接收的时候直接转成发送的对象类型就行了。

Client端

public class Client { 

 public static void main(String[] args) throws InterruptedException {
  EventLoopGroup worker = new NioEventLoopGroup();
  Bootstrap b = new Bootstrap();
  b.group(worker)
  .channel(NioSocketChannel.class)
  .handler(new ChannelInitializer<SocketChannel>() {
   @Override
   protected void initChannel(SocketChannel sc) throws Exception {
    //ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
    //sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));
    //sc.pipeline().addLast(new StringDecoder());
    sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
    sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
    sc.pipeline().addLast(new ClientHandler());
   }
  });
  ChannelFuture f=b.connect("127.0.0.1",8765).sync();
  for(int i=1;i<=5;i++){
   Send send = new Send();
   send.setId(i);
   send.setMessage("message"+i);
   send.setName("name"+i);
   f.channel().writeAndFlush(send);
  }
  f.channel().closeFuture().sync();
  worker.shutdownGracefully();
 }
} 

ClientHandler端

public class ClientHandler extends ChannelHandlerAdapter{
  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
    throws Exception {
   cause.printStackTrace();
   ctx.close();
  } 

  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg)
    throws Exception {
   Receive receive = (Receive) msg;
   System.out.println("server反馈:"+receive);
  }
} 

send类

public class Send implements Serializable { 

 /**
  * serialVersionUID:TODO(用一句话描述这个变量表示什么)
  *
  * @since 1.0.0
  */ 

 private static final long serialVersionUID = 1L; 

 private Integer id;
 private String name;
 private String message; 

 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;
 } 

 public String getMessage() {
  return message;
 } 

 public void setMessage(String message) {
  this.message = message;
 } 

 @Override
 public String toString() {
  return "Send [id=" + id + ", name=" + name + ", message=" + message + "]";
 } 

} 

Receive类

public class Receive implements Serializable{ 

 /**
  * serialVersionUID:TODO(用一句话描述这个变量表示什么)
  * @since 1.0.0
  */ 

 private static final long serialVersionUID = 1L;
 private Integer id;
 private String name;
 private String message;
 private byte[] sss; 

 public byte[] getSss() {
  return sss;
 }
 public void setSss(byte[] sss) {
  this.sss = sss;
 }
 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;
 }
 public String getMessage() {
  return message;
 }
 public void setMessage(String message) {
  this.message = message;
 }
 @Override
 public String toString() {
  return "Receive [id=" + id + ", name=" + name + ", message=" + message + ", sss=" + Arrays.toString(sss) + "]";
 } 

} 

注意:send类和receive这两个类,我们再真实环境开发的时候服务器和客户端往往是两个web应用程序,在这里我们要注意服务端和客户端之间的两个类类名和包名在两端要完全相同。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Netty学习教程之基础使用篇

    什么Netty? Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 也就是说,Netty 是一个基于NIO的客户.服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用.Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发. 我们下面编写四个类 1.用于接收数据的服务器端Socket

  • Netty学习教程之Netty与Marshalling结合发送对象

    前言 之前的一篇文章是Netty简单的学习,我们可以传递一个字符串,那么如果我们想要在Netty中传递一个对象该怎么办呢 ? 那么这个时候我们可以结合Marshalling来传递. 方法如下: 首先需要导入两个Marshalling的依赖包 jboss-marshalling-1.3.0.CR9.jar jboss-marshalling-serial-1.3.0.CR9.jar 注意:我开始学习的时候只导入了第一个jar包,没有导入第二个,结果是不报错,但是客户端和服务端之间传递不了消息.所以

  • jQuery插件学习教程之SlidesJs轮播+Validation验证

    SlidesJs(轮播支持触屏)--官网(http://slidesjs.com) 1.简介 SlidesJs是基于Jquery(1.7.1+)的响应幻灯片插件.支持键盘,触摸,css3转换. 2.代码 <!doctype html> <head> <style> /* Prevents slides from flashing */ #slides { display:none; } </style> <script src="http:/

  • PHP内核学习教程之php opcode内核实现

    opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定. 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数. 这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等. 通常opcode还有另一种称谓:字节码(byte codes). 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Common Intermeditate Language)等等. 1. Opcode简介 opcode是计算

  • Angular4学习教程之DOM属性绑定详解

    前言 DOM 元素触发的一些事件通过 DOM 层级结构传播,事件首先由最内层的元素开始,然后传播到外部元素,直到它们到根元素,这种传播过程称为事件冒泡.本文主要介绍了关于Angular4 DOM属性绑定的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 简介 使用插值表达式将一个表达式的值显示在模版上 <img src="{{imgUrl}}" alt=""> <h1>{{productTitle}}</h1&

  • Angular4学习教程之HTML属性绑定的方法

    前言 本文主要给大家介绍了关于Angular4 HTML属性绑定的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 简介 基本HTML属性 <td [attr.colspan]="tableColspan"></td> Css 类绑定 <!-- 第一种情况 class 类全部替换 --> <div [class]="divClass">CSS 类绑定,[class] 全部替换的例子</d

  • WebGL学习教程之Three.js学习笔记(第一篇)

    webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染. WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏. 原生的WebGl比较复杂,主要通过对顶点着色器和片元着色器的操作,来实现渲染,但实现起来比较复杂,需要一定的数学基础,但更多的是需要学习

  • ES6学习教程之Promise用法详解

    前言 promise用了这么多年了,一直也没有系统整理过.今天整理整理promise的相关东西,感兴趣的可以一起看一看.我尽量用更容易理解的语言来剖析一下promise 我准备分两篇文章来说明一下promise 一篇来理解和使用promise(本篇) 另一篇来从promise使用功能的角度来剖析下promise的源码(下一篇) 1.什么是Promise 我的理解是:实现让我们用同步的方式去写异步代码的一种技术.是异步解决方案的一种. 他可以将多个异步操作进行队列化,让它们可以按照我们的想法去顺序

  • Go语言学习教程之goroutine和通道的示例详解

    目录 goroutine 通道 Range 和 Close Select 官方留的两道练习题 等价的二叉树 网络爬虫 源码地址 goroutine goroutine是由Go运行时管理的轻量级线程. go f(x, y, z)在一个新的goroutine中开始执行f(x, y,z). goroutines运行在相同的地址空间中,所以对共享的内存访问必须同步.sync包提供了基本的同步原语(synchronization primitives),比如互斥锁(mutual exclusion loc

  • Angular2学习教程之ng中变更检测问题详解

    开发中遇到的问题 在开发中遇到一个这样的问题,代码不便透露,这里用简单的例子还原一下问题所在: 有三个组件,第一个是用来展示Todo列表的组件TodoComponent,Todo是个类,包含id和name属性. @Component({ selector: 'todo-list', template: ` <p *ngFor='let item of todos'>{{ item.name }}</p> `, }) export class TodoComponent{ @Inpu

  • React Native学习教程之Modal控件自定义弹出View详解

    前言 最近在学习RN,好多知识都懒得写,趁今天有空,来一发吧,Modal控件的一个小demo:下面话不多说了,来一起看看详细的介绍吧. 参考文章地址:http://reactnative.cn/docs/0.27/modal.html#content Modal组件可以用来覆盖包含React Native根视图的原生视图(如UIViewController,Activity). 在嵌入React Native的混合应用中可以使用Modal.Modal可以使你应用中RN编写的那部分内容覆盖在原生视

随机推荐