Gradle 的优势 原文:https://blog.csdn.net/achenyuan/article/details/80682288 javascript
1. 按约定声明构建和建设;
2. 强大的支持多工程的构建;
3. 强大的依赖管理(基于Apache Ivy),提供最大的便利去构建工程;
4. 全力支持已有的 Maven 或者Ivy仓库基础建设;
5. 支持传递性依赖管理,在不须要远程仓库和pom.xml和ivy配置文件的前提下;
6. 基于groovy脚本构建,其build脚本使用groovy语言编写;
7. 具备普遍的领域模型支持构建;
8. 深度 API;
9. 易迁移;
10. 自由和开放源码,Gradle是一个开源项目,基于 ASL 许可。php
下面是Gradle 基本配置的简介
build.gradle (做用相似于 maven 中的epom 文件)html
plugins { id 'java' id 'war' } group 'gradle02-projext' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' testCompile group: 'junit', name: 'junit', version: '4.12' }
原文位置(http://www.javashuo.com/article/p-kybxzkni-kr.html)java
目录文件 | 做用 |
---|---|
.gradle | gradle项目产生文件(自动编译工具产生的文件) |
.idea | IDEA项目文件(开发工具产生的文件) |
app | 其中一个module,复用父项目的设置,可与父项目拥有相同的配置文件 |
build | 自动构建时生成文件的地方 |
gradle | 自动完成gradle环境支持文件夹 |
.gitignore | git源码管理文件 |
build.gradle | gradle 项目自动编译的配置文件 |
gradle.properties | gradle 运行环境配置文件 |
gradlew | 自动完成 gradle 环境的linux mac 脚本,配合gradle 文件夹使用 |
gradlew.bat | 自动完成 gradle 环境的windows 脚本,配合gradle 文件夹使用 |
local.properties | Android SDK NDK 环境路径配置 |
*.iml | IDEA 项目文件 |
setting.gradle | gradle 项目的子项目包含文件 |
gitignore 该文件是源码管理的配置文件,不在该文讲解。node
既然gradle 是多 module形式,那么咱们来看看 setting.gradle 配置的内容python
rootProject.name = 'gradle'
从上面目录的配置文件内容来看,整个project也算是一个module,若是改module底下还有module,就能够经过setting.gradle配置进来,使得该module底下的gradle,从app module底下能够看出,module最少要含有 build.gradle文件,这个module的项目编译文件,该module依赖什么插件对该目录进行编译都在此配置,好比android与android-library,其余内容可继承父类的linux
一样maven项目须要依赖,Gradle也须要jar包android
可是Gradle的jar包去哪里找呢 根据Build.Gradle 已经指出来了git
repositories {
mavenCentral() maven中心仓库
}
网址是https://search.maven.org/ 使用搜狗浏览器个人打不开,因此我使用了谷歌程序员
里面有一个jar包是将netty全部的jar包都包含了
我都拷贝出来吧
maven版本下的 还不让我copy
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <veresion>5.0.0.Alpha2<version> </dependency>
'io.netty:netty-all:4.1.34.Final'
E:\sturts2\gradle03-projext>gradle clean build BUILD SUCCESSFUL in 12s 2 actionable tasks: 2 executed E:\sturts2\gradle03-projext>
下面先上一个代码,输出helloworld 我再学习的时候,也是一脸懵或许等一下就行了吧
按照个人习惯,先写配置
plugins { id 'java' id 'war' } group 'gradle03-projext' version '1.0' sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { /*testCompile group: 'junit', name: 'junit', version: '4.11'*/ testCompile group: 'junit', name: 'junit', version: '4.12' compile( 'io.netty:netty-all:4.1.34.Final' ) }
TestServer
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * Description: gradle03 * Created by lenovo on 2019/4/17 19:39 */ public class TestServer { public static void main (String[] args) throws InterruptedException { /*netty中大量的就是对线程的处理对线程的控制,对io的一些异步的操做*/ /*先定义两个线程组NIo 就是异步的*/ /*事件循环组:*/ EventLoopGroup bossLoopGroup = new NioEventLoopGroup(); EventLoopGroup workLoopGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossLoopGroup,workLoopGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); bossLoopGroup.shutdownGracefully(); workLoopGroup.shutdownGracefully(); } }
TestHttpServerHandler
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.*; import io.netty.util.CharsetUtil; import javax.servlet.http.HttpServlet; import java.nio.charset.Charset; /** * Description: gradle03 * Created by lenovo on 2019/4/17 20:50 */ public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> { @Override protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception { if (msg instanceof HttpRequest){ ByteBuf content = Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content); response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain"); response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes()); ctx.writeAndFlush(response); } } }
TestServerInitializer
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpServerCodec; /** * Description: gradle03 * Created by lenovo on 2019/4/17 20:46 */ public class TestServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("httpServerCode",new HttpServerCodec()); pipeline.addLast("testHttpServletHandler",new TestHttpServerHandler()); } }
浏览器中是能够访问到的
http://localhost:8899/
如今分析时间执行的流程,和方法回调
执行结果就是这个
channelRegister
channelRegister
channelActive
channelActive
channelReadComplete
等你停下来3秒,管道就自动取消了注册
channelRegister
channelRegister
channelActive
channelActive
channelReadComplete
channelReadComplete
channelInactive channelUnregister
使用netty能作什么,也是对请求进行响应
Netty并没与实现servlet规范,netty编写代码要实现的步骤
1.编写服务器
2.在服务器中编写咱们自定义的Servletinitializer对象
3.在Servletinitializer中去使用不少的handler
如今再放上一个例子 客户端通讯
服务端
package com.netty.chatting; import com.netty.socket.MyServletInitializer; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; /** * Description: gradle03 * Created by lenovo on 2019/4/18 10:14 */ public class MyChattingServer { public static void main (String[] args) throws InterruptedException { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class). childHandler(new MychatServerInitalizer()); serverBootstrap.bind(8899).sync(); bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }
package com.netty.chatting; import com.netty.socket.MyHttpServerHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.LengthFieldBasedFrameDecoder; import io.netty.handler.codec.LengthFieldPrepender; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; import java.net.Socket; /** * Description: gradle03 * Created by lenovo on 2019/4/18 10:21 */ /* public class MychatServerInitalizer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new DelimiterBasedFrameDecoder(4096, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new MyChatServerHandler()); } } */ public class MychatServerInitalizer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new DelimiterBasedFrameDecoder(4096, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast("testHttpServletHandler",new MyChatServerHandler()); } }
package com.netty.chatting; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.util.concurrent.GlobalEventExecutor; import jdk.nashorn.internal.objects.Global; /** * Description: gradle03 * Created by lenovo on 2019/4/18 10:43 */ public class MyChatServerHandler extends SimpleChannelInboundHandler<String> { public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { Channel channel = ctx.channel(); channelGroup.forEach(ch -> { if (channel!=ch){ ch.writeAndFlush(channel.remoteAddress()+"发送的消息"+msg+"\n"); }else{ ch.writeAndFlush("本身"+msg+"\n"); } }); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { super.handlerAdded(ctx); Channel channel = ctx.channel(); channelGroup.writeAndFlush("服务器-"+channel.remoteAddress()+"加入\n"); channelGroup.add(channel); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { super.handlerRemoved(ctx); Channel channel = ctx.channel(); channelGroup.writeAndFlush("服务器-"+channel.remoteAddress()+"离开\n"); System.out.println(channelGroup.size()); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); Channel channel = ctx.channel(); System.out.println(channel.remoteAddress()+"上线\n"); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); Channel channel = ctx.channel(); System.out.println(channel.remoteAddress()+"下线\n"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); ctx.close(); } }
客户端
package com.netty.chatting; import com.netty.socket.MySClientInitializer; import com.sun.org.apache.bcel.internal.generic.NEW; import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * Description: gradle03 * Created by lenovo on 2019/4/18 11:16 */ public class MyChatClientServer { public static void main (String[] args){ EventLoopGroup eventExecutors = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventExecutors).channel(NioSocketChannel.class).handler(new MyChatClientInitializer()); Channel channel = bootstrap.connect("localhost",8899).sync().channel(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); for (;;){ channel.writeAndFlush(bufferedReader.readLine()+"\r\n"); } } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { eventExecutors.shutdownGracefully(); } } }
package com.netty.chatting; import com.netty.socket.MyClientHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.util.CharsetUtil; public class MyChatClientInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new DelimiterBasedFrameDecoder(4096, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast("testHttpServletHandler",new MyChatClientServerHandler()); } }
package com.netty.chatting; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * Description: gradle03 * Created by lenovo on 2019/4/18 11:17 */ public class MyChatClientServerHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); } }
放上执行结果
前后打开了三个客户端
下面是长链接的例子
package com.netty.longConnection; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Description: gradle03 * Created by lenovo on 2019/4/18 15:37 */ public class MyServer { public static void main (String[] args) throws InterruptedException { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class). handler(new LoggingHandler(LogLevel.INFO)). childHandler(new MyServletInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().close().sync(); /* bossGroup.shutdownGracefully(); workGroup.shutdownGracefully();*/ } }
package com.netty.longConnection; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.timeout.IdleStateHandler; import java.util.concurrent.TimeUnit; /** * Description: gradle03 * Created by lenovo on 2019/4/18 15:41 */ public class MyServletInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new IdleStateHandler(5,7,10, TimeUnit.SECONDS)); pipeline.addLast(new MyServerHandler()); } }
package com.netty.longConnection; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.timeout.IdleStateEvent; /** * Description: gradle03 * Created by lenovo on 2019/4/18 15:48 */ public class MyServerHandler extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { super.userEventTriggered(ctx, evt); if (evt instanceof IdleStateEvent){ IdleStateEvent event = (IdleStateEvent) evt; String eventType = null; switch (event.state()){ case READER_IDLE: eventType="读空闲"; case WRITER_IDLE: eventType="写空闲"; case ALL_IDLE: eventType="读写空闲"; break; } System.out.println(ctx.channel().remoteAddress()+"超时事件"+eventType); ctx.channel().close(); } } }
netty实现服务端与客户端的长联统统信
<%-- Created by IntelliJ IDEA. User: lenovo Date: 2019/4/17 Time: 18:19 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>webSocket客户端</title> <script> var socket; if(window.WebSocket){ socket= new WebSocket("ws://localhost:8899/ws"); socket.onmessage = function (event) { var ta = document.getElementById("responseText"); ta.value = ta.value+"\n"+event.data; } socket.onopen = function (event) { var ta = document.getElementById("responseText"); ta.value="链接开启"; } socket.onclose= function (event) { var ta = document.getElementById("responseText"); ta.value = ta.value+"\n"+"链接关闭"; } }else { alert("浏览器不支持websocket"); } function send(message) { if(!window.WebSocket){ return; }if(socket.readyState == WebSocket.OPEN){ socket.send(message); }else { alert("链接还没有开启") } } </script> </head> <body> <form onsubmit="false"> <textarea name="message" style="width: 400px; height: 200px"></textarea> <input type="button" value="发送数据" onclick="send(this.form.message.value)"> <h3>服务端输出:</h3> <textarea id="responseText" style="width: 400px; height: 300px;"></textarea> <input type="button" onclick="javascript:document.getElementById('responseText').value=''" value="清空内容"> </form> </body> </html>
package com.netty.ServerSocke; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoop; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Description: gradle03 * Created by lenovo on 2019/4/18 16:38 */ public class MyServer { public static void main (String[] args) throws InterruptedException { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new MyServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind("localhost", 8899).sync(); /* channelFuture.channel().close().sync(); bossGroup.shutdownGracefully(); workGroup.shutdownGracefully();*/ } }
package com.netty.ServerSocke; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.stream.ChunkedWriteHandler; /** * Description: gradle03 * Created by lenovo on 2019/4/18 16:43 */ public class MyServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast( new HttpServerCodec()); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new HttpObjectAggregator(8192)); pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); pipeline.addLast(new MyServerhandler()); } }
package com.netty.ServerSocke; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import java.time.LocalDateTime; /** * Description: gradle03 * Created by lenovo on 2019/4/18 17:13 */ public class MyServerhandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { System.out.println("收到消息"+msg.text()); ctx.channel().writeAndFlush(new TextWebSocketFrame("服务事件"+ LocalDateTime.now())); } @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { super.handlerAdded(ctx); System.out.println("handlerAdded"+ctx.channel().id()); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { super.handlerRemoved(ctx); System.out.println("handlerremove"+ctx.channel().id().asLongText()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { super.exceptionCaught(ctx, cause); System.out.println("异常发生exceptionCaught"); ctx.close(); } }
下载protobuf
Protocol Buffer 简称 ProtoBuf 是用于结构化数据串行化的灵活、高效、自动的方法,又如 XML,不过它更小、更快、也更简单。你能够定义本身的数据结构,而后使用代码生成器生成的代码来读写这个数据结构。你甚至能够在无需从新部署程序的状况下更新数据结构
网址(https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1)
二选一
下载成功了以后别忘了在你的环境变量中进行配置。
选择你对应的版本
在google中去寻找你的jar包
https://search.maven.org/artifact/com.google.protobuf/protobuf-java/3.7.1/bundle
不过好像不能复制,我只能手写了
'com.google.protobuf:protobuf-java:3.7.1'
com.google.protobuf:protobuf-java-util:3.7.1
在idea中使用protobef 也是花费了我一番力气,首先毋庸置疑先安装插件
此时我建立的Student.proto文件的图标应该发生变化的可是没有发生变化
尝试另一种解决方案
这下就发生了变化

详细讲解配置文件的链接(https://www.meiwen.com.cn/subject/chzzcxtx.html)
syntax = "proto2";
package cn.edu.aynu.protobuf; //能够自定义
option optimize_for = SPEED; //默认也是speed加速解析
option java_package = "cn.edu.aynu.protobuf";
option java_outer_classname = "DataInfo"; //这个名字也能够本身定义
message Student{
required string name =1; //每个字段都有惟一标识符这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不可以再改 变
optional int32 age =2;
optional string address = 3;
}
所指定的消息字段修饰符必须是以下之一:
² required:一个格式良好的消息必定要含有1个这种字段。表示该值是必需要设置的;
² optional:消息格式中该字段能够有0个或1个值(不超过1个)。
² repeated:在一个格式良好的消息中,这种字段能够重复任意屡次(包括0次)。重复的值的顺序会被保留。表示该值能够重复,至关于Java中的List。
因为一些历史缘由,基本数值类型的repeated的字段并无被尽量地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。如:
repeated int32 samples = 4 [packed=true]; |
required是永久性的:在将一个字段标识为required的时候,应该特别当心。若是在某些状况下不想写入或者发送一个required的 字段,将原始该字段修饰符更改成optional可能会遇到问题——旧版本的使用者会认为不含该字段的消息是不完整的,从而可能会无目的的拒绝解析。在这 种状况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google的一些工程师得出了一个结论:使用required弊多于利;他们更 愿意使用optional和repeated而不是required。固然,这个观点并不具备广泛性。
在终端上输入命令
表示在protoc --java_out= src/mian/java 这个目录下生成代码,源文件在
src/protobuf/Student.proto 目录下。
这里出现了一个小问题我再斜着跳语句的时候
E:\sturts2\gradle05-project>protoc --java_out = src/main/java src/protobuf/Student.proto src/main/java: Permission denied
我查了不少,可是网上几乎没有人遇到过这个问题,根本搜不到后来我又敲了一遍
E:\sturts2\gradle05-project>protoc --java_out=src/main/java src/protobuf/Student.proto
发现问题了吧,对就是空格,= 好先后的空格。把先后的空格去掉就执行成功了。
须要指出的是,你绝对不能修改生成的DataInfo 这个文件,由于如今咱们还不具有修改这个文件的个水平。
新建一个java类
package cn.edu.aynu.protobuf; import com.google.protobuf.InvalidProtocolBufferException; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:26 */ public class ProobufTest { public static void main (String[] args) throws InvalidProtocolBufferException { DataInfo.Student student = DataInfo.Student.newBuilder().setName("张三"). setAge(20).setAddress("北京").build(); //先构建一个java对象 byte[] bytes = student.toByteArray(); //将java对象转换为一个字节数组 DataInfo.Student student1 = DataInfo.Student.parseFrom(bytes);//从字节数组中将java对象的信息给恢复过来 System.out.println(student1.getAddress()); System.out.println(student1.getName()); System.out.println(student1.getAge()); } }
执行结果
我再执行下一个程序的时候遇到了一个错误
com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ende
或者是没法远程链接
个人缘由是我写错了一个关闭
应该写成 channelFuture.channel().closeFuture().sync();
结果写成了 channelFuture.channel().close().sync();
因此就致使了上面的两个问题,若是你将下面连个注释掉虽然服务不会停可是当你启动客户端的时候就会发生 链接被拒绝,没有远程服务
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
下面粘上我正确的代码
package cn.edu.aynu.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:50 */ public class MyServer { public static void main (String[] args) throws InterruptedException { /*同理首先要构建事件*/ EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class). handler(new LoggingHandler(LogLevel.INFO)). childHandler(new ServerInitializer()); // 绑定端口后 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); // 关闭端口 channelFuture.channel().closeFuture().sync(); /* channelFuture.channel().close().sync();*/ //关闭两个线程 bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:55 */ public class ServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtobufVarint32FrameDecoder()); pipeline.addLast(new ProtobufDecoder(DataInfo.Student.getDefaultInstance()));//解码器把字节数组转换为真正的对象 pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast(new ProtobufEncoder()); pipeline.addLast(new MyServerHandler()); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:59 */ public class MyServerHandler extends SimpleChannelInboundHandler<DataInfo.Student> { @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Student msg) throws Exception { System.out.println(msg.getAddress()); System.out.println(msg.getAge()); System.out.println(msg.getName()); } }
客户端
package cn.edu.aynu.netty; import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:07 */ public class MyClient { public static void main (String[] args) throws IOException, InterruptedException { NioEventLoopGroup eventExecutors = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventExecutors).channel(NioSocketChannel.class).handler(new MyClientInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { eventExecutors.shutdownGracefully(); } } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:15 */ public class MyClientInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtobufVarint32FrameDecoder()); pipeline.addLast(new ProtobufDecoder(DataInfo.Student.getDefaultInstance()));//解码器把字节数组转换为真正的对象 pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast(new ProtobufEncoder()); pipeline.addLast(new MyClientHandler()); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:15 */ public class MyClientHandler extends SimpleChannelInboundHandler<DataInfo.Student> { @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Student msg) throws Exception { } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); DataInfo.Student student1 = DataInfo.Student.newBuilder().setName("张三").setAddress("背景").setAge(23).build(); ctx.channel().writeAndFlush(student1); } }
syntax = "proto2"; package cn.edu.aynu.protobuf; //能够自定义 option optimize_for = SPEED; //默认也是speed加速解析 option java_package = "cn.edu.aynu.netty"; option java_outer_classname = "DataInfo"; message Student{ required string name =1; //每个字段都有惟一标识符 optional int32 age =2; optional string address = 3; }
多协议消息支援
syntax = "proto2"; package cn.edu.aynu.protobuf; //能够自定义 option optimize_for = SPEED; //默认也是speed加速解析 option java_package = "cn.edu.aynu.netty"; option java_outer_classname = "DataInfo"; message MyMessage{ enum DataType{ StudentType =1; DogType =2; CatType =3; } required DataType data_type = 1; oneof dataBody{ Student student =2; Dog dog =3; Cat cat =4; } } message Dog{ optional string name =1; optional int32 age =2; } message Cat{ optional string name =1; optional int32 age =2; } message Student{ required string name =1; //每个字段都有惟一标识符 optional int32 age =2; optional string address = 3; }
package cn.edu.aynu.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:50 */ public class MyServer { public static void main (String[] args) throws InterruptedException { /*同理首先要构建事件*/ EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,workGroup).channel(NioServerSocketChannel.class). handler(new LoggingHandler(LogLevel.INFO)). childHandler(new ServerInitializer()); // 绑定端口后 ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); // 关闭端口 channelFuture.channel().closeFuture().sync(); /* channelFuture.channel().close().sync();*/ //关闭两个线程 bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:55 */ public class ServerInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtobufVarint32FrameDecoder()); pipeline.addLast(new ProtobufDecoder(DataInfo.MyMessage.getDefaultInstance()));//解码器把字节数组转换为真正的对象 pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast(new ProtobufEncoder()); pipeline.addLast(new MyServerHandler()); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * Description: gradle05 * Created by lenovo on 2019/4/19 17:59 */ public class MyServerHandler extends SimpleChannelInboundHandler<DataInfo.MyMessage> { @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.MyMessage msg) throws Exception { DataInfo.MyMessage.DataType dataType = msg.getDataType(); if (dataType == DataInfo.MyMessage.DataType.StudentType){ DataInfo.Student student = msg.getStudent(); System.out.println(student.getAddress()); System.out.println(student.getAge()); System.out.println(student.getName()); }else if(dataType == DataInfo.MyMessage.DataType.DogType){ DataInfo.Dog dog = msg.getDog(); System.out.println(dog.getName()); System.out.println(dog.getAge()); }else{ DataInfo.Cat cat = msg.getCat(); System.out.println(cat.getName()); System.out.println(cat.getAge()); } } }
client
package cn.edu.aynu.netty; import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:07 */ public class MyClient { public static void main (String[] args) throws IOException, InterruptedException { NioEventLoopGroup eventExecutors = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventExecutors).channel(NioSocketChannel.class).handler(new MyClientInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync(); channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { eventExecutors.shutdownGracefully(); } } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:15 */ public class MyClientInitializer extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new ProtobufVarint32FrameDecoder()); pipeline.addLast(new ProtobufDecoder(DataInfo.MyMessage.getDefaultInstance()));//解码器把字节数组转换为真正的对象 pipeline.addLast(new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast(new ProtobufEncoder()); pipeline.addLast(new MyClientHandler()); } }
package cn.edu.aynu.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import java.util.Random; /** * Description: gradle05 * Created by lenovo on 2019/4/19 18:15 */ public class MyClientHandler extends SimpleChannelInboundHandler<DataInfo.MyMessage> { @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.MyMessage msg) throws Exception { } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { super.channelActive(ctx); DataInfo.MyMessage message = null; int randomInt = new Random().nextInt(3); if (0==randomInt){ message= DataInfo.MyMessage.newBuilder(). setDataType(DataInfo.MyMessage.DataType.StudentType). setStudent(DataInfo.Student.newBuilder(). setName("张三").setAddress("背景").setAge(23).build()).build(); }else if(1==randomInt){ message= DataInfo.MyMessage.newBuilder(). setDataType(DataInfo.MyMessage.DataType.DogType). setDog(DataInfo.Dog.newBuilder(). setName("小汪").setAge(2).build()).build(); }else { message= DataInfo.MyMessage.newBuilder(). setDataType(DataInfo.MyMessage.DataType.CatType). setCat(DataInfo.Cat.newBuilder(). setName("小猫").setAge(3).build()).build(); } DataInfo.Student student1 = DataInfo.Student.newBuilder().setName("张三").setAddress("背景").setAge(23).build(); ctx.channel().writeAndFlush(message); } }
接下来是apache Thrift (详细讲解能够参考 https://www.cnblogs.com/fingerboy/p/6424248.html)
简单来讲,是Facebook公布的一款开源跨语言的RPC框架.
Thrift最初由Facebook开发的,后来提交给了Apache基金会将Thrift做为一个开源项目。当时facebook开发使用它是为了解决系统中各系统间大数据量的传输通讯以及系统之间语言环境不一样须要跨平台的特性,因此Thrift是支持跨语言,好比C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml都支持。Thrift是一个典型的CS结构,客户端和服务端可使用不一样的语言开发。既然客户端和服务端能使用不一样的语言开发,那么必定就要有一种中间语言来关联客户端和服务端的语言,没错,这种语言就是IDL(Interface Description Language)。
RPC全称为Remote Procedure Call,意为远程过程调用.
假设有两台服务器A,B.A服务器上部署着一个应用a,B服务器上部署着一个应用b,如今a但愿可以调用b应用的某个函数(方法),可是两者不在同一个进程内,不能直接调用,就须要经过网络传输,在AB服务器之间建一条网络传输通道,a把参数传过去,b接收到参数调用本身的方法,获得结果,再经过网络传回给a,简单讲就是A经过网络来调用B的过程.这个过程要涉及的东西不少,好比多线程,Socket,序列化反序列化,网络I/O,很复杂,因而牛掰的程序员把这些封装起来作成一套框架,供你们使用,就是RPC框架.
下载地址(http://thrift.apache.org/download),而后将下载
不会安装的能够参考这个(https://blog.csdn.net/haihaa/article/details/76577797)
在idea 下使用Gradle写一个Thrift的例子
注意图标的变化
namespace java thrift.generated typedef i16 short typedef i32 int typedef i64 long typedef bool boolean typedef string String struct Person{ 1:optional String username, 2:optional int age, 3:optional boolean married } exception DataException{ 1:optional String message, 2:optional String callStack, 3:optional String data } service PersonService{ Person getPersonByUsername(1:required String username) throws (1:DataException dataException), void savePerson(1:required Person person) throws(1:DataException dataException) }
而后再终端中运行这句话
E:\sturts2\gradle05-project>thrift --gen java src/Thrift/data.thrift
若是你在环境变量中已经配置好了,cmd命令行中也能访问到,可是在idea 中的终端上不能访问,那么你能够尝试将程序都关掉,或者将电脑重启
这时再打开就能够了。
当在idea终端总运行后会出现一个
由于生成的这个目录不在java 目录下,因此将其拷贝到java 目录下
须要导入依赖
"org.apache.thrift.:thrift-maven-plugin:0.10.0"
thrift的一个架构
package cn.edu.aynu.thrift; import com.sun.org.apache.bcel.internal.generic.NEW; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.TServer; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.THttpClient; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TTransportException; import thrift.generated.PersonService; /** * 这是服务端 */ public class ThriftServer { public static void main (String[] args) throws TTransportException { TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(8899); THsHaServer.Args workerThreads = new THsHaServer.Args(serverSocket).minWorkerThreads(2).maxWorkerThreads(4); PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl()); workerThreads.protocolFactory(new TCompactProtocol.Factory()); workerThreads.transportFactory(new TFramedTransport.Factory()); workerThreads.processorFactory(new TProcessorFactory(processor)); TServer server = new THsHaServer(workerThreads); System.out.println("Thrift Server Started"); //这是一个死循环 server.serve(); } }
package cn.edu.aynu.thrift; import org.apache.thrift.TException; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import thrift.generated.Person; import thrift.generated.PersonService; /** * Description: gradle05 * Created by lenovo on 2019/4/20 11:20 */ public class ThriftClient { public static void main (String[] args){ TTransport transport = new TFramedTransport(new TSocket("localhost",8899,600)); TCompactProtocol protocol = new TCompactProtocol(transport); PersonService.Client client = new PersonService.Client(protocol); try { transport.open(); Person person = client.getPersonByUsername("张三"); System.out.println(person.getAge()); System.out.println(person.getUsername()); System.out.println(person.isMarried()); System.out.println("-----------------------"); Person person1 = new Person(); person1.setUsername("李艾"); person1.setAge(23); person1.setMarried(true); client.savePerson(person1); } catch (TException e) { e.printStackTrace(); }finally { transport.close(); } } }
package cn.edu.aynu.thrift; import org.apache.thrift.TException; import thrift.generated.DataException; import thrift.generated.Person; import thrift.generated.PersonService; /** * Description: gradle05 * Created by lenovo on 2019/4/20 10:58 */ public class PersonServiceImpl implements PersonService.Iface { @Override public Person getPersonByUsername(String username) throws DataException, TException { System.out.println("Got client Param"+username); Person person = new Person(); person.setUsername(username); person.setAge(20); person.setMarried(false); return person; } @Override public void savePerson(Person person) throws DataException, TException { System.out.println("Got Client Param"); System.out.println(person.getUsername()); System.out.println(person.getAge()); System.out.println(person.isMarried()); } }
运行结果
当你执行 gradle wrapper
会出现3个文件
还能够在built.gradle中指定版本
这样就不须要在终端中输入命令。
Grpc 的一些了解知识
官网(https://grpc.io/docs/tutorials/basic/java.html)
https://grpc.io/docs/quickstart/java.html
Grpc与Gradle整合,我是失败了,大家能够试试,我如今先往下看,等过段时间不忙了,我再从新看一下官网把这个问题给找出来。
https://github.com/grpc/grpc-java
我这个目前是一直都不对,我先记录一下等回头再学习
下面这个例子是grpc 通讯实例与JVM 回调
我上面最基本的环境都搭建不起来多以这个例子我也跑不起来,先过,看下面的例子,等我有空了再把这个部份内容补充回来
。。。。。。。。。。。。。。。。。。。。。。。
全部的有关grpc 的内容都暂且略过。
。。。。。。。。。。
1。grpc 服务器流式调用实现
2.grpc 双向流式数据通讯详解
3.grpc 与Gradle 流式整合
下面就主要讲解,Gradle插件问题解决方案,与Nodejs 环境搭建
目前我是真是坚持不下去了,真的是很难啊,环境打很差,我仍是先看基础的吧,能看完的都是人才啊。