1.pom.xml:

当然,也可建立个java工程把jar包放进去

 1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"2     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">3     <modelVersion>4.0.0</modelVersion>4     <groupId>netty-demo</groupId>5     <artifactId>com.kingdee</artifactId>6     <version>0.0.1-SNAPSHOT</version>7     <properties>8         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>9         <spring.version>3.2.5.RELEASE</spring.version>
10         <spring.rabbit.version>1.3.5.RELEASE</spring.rabbit.version>
11     </properties>
12     <dependencies>
13         <dependency>
14             <groupId>org.springframework</groupId>
15             <artifactId>spring-context</artifactId>
16             <version>${spring.version}</version>
17         </dependency>
18
19         <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
20         <dependency>
21             <groupId>io.netty</groupId>
22             <artifactId>netty-all</artifactId>
23             <version>4.0.23.Final</version>
24         </dependency>
25
26         <!-- https://mvnrepository.com/artifact/log4j/log4j -->
27         <dependency>
28             <groupId>log4j</groupId>
29             <artifactId>log4j</artifactId>
30             <version>1.2.17</version>
31         </dependency>
32
33         <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
34         <dependency>
35             <groupId>commons-logging</groupId>
36             <artifactId>commons-logging</artifactId>
37             <version>1.1.1</version>
38         </dependency>
39
40         <dependency>
41             <groupId>com.google.protobuf</groupId>
42             <artifactId>protobuf-java</artifactId>
43             <version>3.0.0</version>
44         </dependency>
45     </dependencies>
46 </project>

2.msg.proto,把它转换成java代码,再拷贝到对应的包下,利用proto.exe工具生成

mgs.proto:

它是传输的实体类,有两个部分,client和service

传输数据时可以直接.来选择调用哪个对象

package com.netty.demo;
message Client {  required string head = 1;  required string body = 2;
}message Server {required int32 code=1;required string message=2;
}

在protoc.exe下面放proto文件,通过命令生成这个传输实体类

3.客户端代码:

Client.java:

package com.netty.demo.client;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;public class Client {public static String host = "127.0.0.1";public static int port = 8787;public static void main(String[] args) {EventLoopGroup worker = new NioEventLoopGroup();Bootstrap b = new Bootstrap();b.group(worker);b.channel(NioSocketChannel.class);b.handler(new ClientInitializer());try {ChannelFuture f = b.connect(host, port).sync();f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {worker.shutdownGracefully();}}
}

ClientHandler.java(处理客户端消息发送和收到服务端消息的处理,但一般情况下是不会在这里写发送消息的逻辑的,只是为了写demo,所以把发消息写在这里面)

package com.netty.demo.client;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;import com.google.protobuf.Message;
import com.netty.demo.Msg;public class ClientHandler extends SimpleChannelInboundHandler<Message> {/*** */protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {System.out.println("Server say : " + msg.toString());}/*** */public void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("Client active ");Msg.Client msg = Msg.Client.newBuilder().setHead("Content-Type:application/json;charset=UTF-8").setBody("hello world!").build();ctx.writeAndFlush(msg);super.channelActive(ctx);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("Client close ");super.channelInactive(ctx);}}

ClientInitializer.java(初始化Chanel,如解码,加密等),最早的netty传protobuf,是需要手动toByteArrary()把传输对象序列化成二进制流发出去,接收端再手动反序列化还原成传输对象。

但是后来通过设置protubuf编码解码器,就可以自动实现序列化和反序列化,传输时只需要把实体发出去就行了。

package com.netty.demo.client;import com.netty.demo.Msg;import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;public class ClientInitializer extends ChannelInitializer<SocketChannel> {protected void initChannel(SocketChannel ch) throws Exception {// decodedch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));//这里是收到服务端发过来的消息,所以是对服务端的response解码ch.pipeline().addLast(new ProtobufDecoder(Msg.Server.getDefaultInstance()));// encodedch.pipeline().addLast(new LengthFieldPrepender(4));ch.pipeline().addLast(new ProtobufEncoder());// 注册handlerch.pipeline().addLast(new ClientHandler());}}

4.Server端代码:

Server.java

package com.netty.demo.server;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;public class Server {private static int port = 8787;public static void main(String[] args) {EventLoopGroup boss = new NioEventLoopGroup();EventLoopGroup worker = new NioEventLoopGroup();ServerBootstrap server = new ServerBootstrap();server.group(boss, worker);server.channel(NioServerSocketChannel.class);server.childHandler(new ServerInitializer());server.option(ChannelOption.SO_BACKLOG, 128);server.childOption(ChannelOption.SO_KEEPALIVE, true);try {//绑定端口 同步等待成功ChannelFuture f = server.bind(port).sync();//等待服务端监听端口关闭f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {worker.shutdownGracefully();boss.shutdownGracefully();}}
}

ServerHandler.java:

package com.netty.demo.server;import java.net.InetAddress;import com.google.protobuf.Message;
import com.netty.demo.Msg;
import com.netty.demo.Msg.Client;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;/*** 处理客户端连接时的handler* * @author shizhengchao32677* */
public class ServerHandler extends SimpleChannelInboundHandler<Message> {/*** 收到客户端发过来的消息*/protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {// 收到消息直接打印输出System.out.println(msg.getClass());Msg.Server response = null;if(msg instanceof Msg.Client) {Msg.Client clientMsg = (Client) msg;System.out.println(ctx.channel().remoteAddress() + " Say : " + clientMsg.getBody());response = Msg.Server.newBuilder().setCode(0).setMessage("Received client message success").build();} else {response = Msg.Server.newBuilder().setCode(-1).setMessage("client message is illegal").build();System.out.println("client message is illegal");}// 返回客户端消息 - 我已经接收到了你的消息ctx.writeAndFlush(response);}/** 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候)*/public void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !");String welcome = "Welcome to " + InetAddress.getLocalHost().getHostName() + " service!";Msg.Server response = Msg.Server.newBuilder().setCode(101).setMessage(welcome).build();ctx.writeAndFlush(response);super.channelActive(ctx);}}

ServerInitializer.java

package com.netty.demo.server;import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;import com.netty.demo.Msg;public class ServerInitializer extends ChannelInitializer<SocketChannel> {protected void initChannel(SocketChannel ch) throws Exception {// decodedch.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));//解码客户端发过来的消息ch.pipeline().addLast(new ProtobufDecoder(Msg.Client.getDefaultInstance()));// encodedch.pipeline().addLast(new LengthFieldPrepender(4));ch.pipeline().addLast(new ProtobufEncoder());// 注册handlerch.pipeline().addLast(new ServerHandler());}}

运行Server.java和Client.java:

Server输出:RamoteAddress : /127.0.0.1:59693 active !
class com.netty.demo.Msg$Client
/127.0.0.1:59693 Say : hello world!Clientl输出:Client active
Server say : code: 101
message: "Welcome to H4UOJJQSF23HQ91 service!"Server say : code: 0
message: "Received client message success"

ProtoBuf和Netty的简单使用相关推荐

  1. protobuf和socket通信简单实例

    protobuf和socket通信简单实例   protobuf是 Google 公司内部的混合语言数据标准,可以用来定义通信的协议,由于其有序列化和反序列化的操作,减小了存储或通信的数据量,从而达到 ...

  2. 这么说吧,Netty很简单,其实就是个Jar包,是作为通讯组件用的

    极简教程,五分钟快速入门之netty,搭配后面netty实战以及netty源码分析 0 ) 关键词: Netty.NIO.异步.通讯. 1)本质: 一个Jar包,一个NIO框架,是对 socket 网 ...

  3. netty实现简单的rpc,支持服务集群

    netty实现简单的rpc,支持服务集群 前言 简介 环境准备 Netty 处理器链设计 消费者RPC代理工厂设计 netty rpc消费者核心设计 netty rpc生产者核心设计 服务注册.发现以 ...

  4. 【初识Netty使用Netty实现简单的客户端与服务端的通信操作Netty框架中一些重要的类以及方法的解析】

    一.Netty是什么? Netty 由 Trustin Lee(韩国,Line 公司)2004 年开发 本质:网络应用程序框架 实现:异步.事件驱动 特性:高性能.可维护.快速开发 用途:开发服务器和 ...

  5. 基于Netty最简单的WebSocket通讯

    基于Netty最简单的WebSocket通讯 基于Netty最简单的WebSocket通讯 总览 服务端 EasyWsServer EasyWsServerHandler 客户端 EasyWsClie ...

  6. Netty - 一个简单的聊天室小项目

     经过一段时间对Netty的学习,我们对Netty各版本以及像ProtocolBuffers等技术应用都有了不少相关的了解, 我们就用这段时间学到的只是做一个简单的聊天室的小项目来练习自己学到的技术. ...

  7. springboot整合kafka和netty服务简单实例

    文章目录 背景 实体 编写KafkaSender,用于操作kafka 编写netty服务端 netty 服务启动类: NettyServerHandler处理类 Controller 背景 步骤: p ...

  8. netty实现简单时事通讯_简单的Java实现Netty进行通信

    使用Java搭建一个简单的Netty通信例子 看过dubbo源码的同学应该都清楚,使用dubbo协议的底层通信是使用的netty进行交互,而最近看了dubbo的Netty部分后,自己写了个简单的Net ...

  9. netty搭建简单的文件服务器

    在工作中,文件服务器是很常用的,我们经常需要把一些公共资源放到服务器上的某个目录下,通过IP加端口就可以实现文件的查看,下载等功能, 常见的方法像tomcat,将文件放到webapps下,启动tomc ...

  10. netty实现简单时事通讯_使用 RSocket 进行反应式数据传输

    在微服务架构中,不同服务之间通过应用协议进行数据传输.典型的传输方式包括基于 HTTP 协议的 REST 或 SOAP API 和基于 TCP 字节流的 gRPC 等.HTTP 协议的优势在于其广泛的 ...

最新文章

  1. 二、OCR训练时,将txt文件和图片数据转为lmdb文件格式
  2. FPGA之道(2)FPGA应用方向
  3. python编程课程上课有用吗-Python培训网络课堂|Python编程软件有哪些功能?
  4. 动态创建DataTable[转]
  5. day24 反射\元类
  6. python--批量下载豆瓣图片
  7. 详细设计 存储分配_零基础学C语言(7):存储类型
  8. 你真的理解clear:both吗?
  9. OpenCV-美食—鲜美滤镜
  10. pandas数据处理实践三(DataFrame.apply、merge、rename,数据预处理、DataFrame.drop_duplicates去重)
  11. HTML基础学习(二)—CSS
  12. 传智播客 多继承以及MRO顺序 学习笔记
  13. 动态在网络图片上写字
  14. 微信小程序地图和百度地图定位位置不一样
  15. 微型计算机设计总结报告,微机课程设计心得体会范文
  16. Microsoft Visual SourceSafe 6.0 关联VS
  17. 关于写作,别那么在意别人的看法,开始干吧
  18. 数据结构——前序线索二叉树及其前序遍历
  19. Cesium Primitives加载大量图标点
  20. BBS系统的设计与实现

热门文章

  1. jwt如何加盐_手把手教你使用JWT实现单点登录
  2. python使用正则验证电子邮件_在Python中使用正则表达式提取电子邮件地址
  3. DL-C_1_week_1_1
  4. 批量归一化Batch Normalization 动手学深度学习v2
  5. Google Cloud Fundamentals简介
  6. 阿里云云计算 36 PolarDB MySQL的管理步骤
  7. 极客大学产品经理训练营 产品思维和产品意识 作业2
  8. diff与patch操作
  9. 440.字典序中的第K小数字
  10. 判断数组是否为某二叉搜索树的后序遍历