包结构长这个样子:java
server包:(服务器相关配置)mongodb
HttpServer:用ver.x建立了一个http服务器,把接收到的req请求传入RPCRequest中;数据库
RPCRequest:解析请求body内容,把信息保存为M(类名) A(方法名) P(参数),同时还拥有invoke()方法,根据m、a、p的数据用反射调用方法。服务器
RPCResponse:没写,用来保存响应信息的。异步
Manager包:(将全部须要被远程调用的方法保存到内容中,加快调用时遍历查询方法的响应速度)函数
MethodManager:里面声明一个HashMap,value是KFunction<*>保存全部被@RPC1注解的方法,同时有addAllMethod()方法,用来保存当前类全部带@RPC1注解的方法。spa
ControllerManager:用HashMap保存全部Controller类,value是KClass<*>,init中须要手动put添加controller类。日志
Service包:(提供业务方法,供调用)code
LoginService:提供业务解决逻辑的方法server
Mongo包:(数据持久层,与数据库打交道,应该写成Dao层的)
UserDao:用户集合的数据库操做。
(2017.7.27更新)
Log包:
Loggin:封装了日志的信息
controller包:
LoginController:请求响应被调用的方法
2018.7.27更新:
原来的版本有几个缺陷:
①没有使用vert.x的mongo,而使用了原生mongo的jdbc;
②对数据库的查询没有实现异步。
①刚开始使用了原生mongodb的jar包和mongoclient对象,可是这种方式没有用到vertx的异步,因此改成 io.vertx.ext.mongo.MongoClient 这个jar包。可是没有删除原来原生的mongodb包,就形成了一个bug。会在执行 val mongoClient = MongoClient.createNonShared(Main.vertx, config) 这条语句的时候报错:clusterListener can not be null。 删除原生mongodb的jar包就能够了。
②改为了vertx的mongo方式就是为了查询数据库的时候使用异步来提升查询效率。刚开始仍是不理解kotlin中的异步写法。
异步就是当前程序正在执行,使用回调执行了另一段代码,若是当前程序执行完了,就会结束,不会获得另外一端代码的结果,如:
1 /* 2 * 查找指定用户名和密码的用户 3 * */ 4 fun findUser(userName:String,pwd:String):String?{ 5 val query=JsonObject().put("name",userName).put("pwd",pwd) 6 var user?=null 7 mongoClient.find("jtest",query,{res-> 8 if (res.succeeded()){ 9 val result=res.result()[0] 10 if (!result.isEmpty){ 11 user=User(result.getString("name"),result.getString("pwd")) 12 } 13 } 14 }) 15 return user 16 }
上面的写法是错误的,由于vertx的mongo的find()方法使用了异步写法,在异步的方法块里面对外面的变量赋值,外面是接收不到的。
正确的写法应该是回调来接收结果。java中想要使用回调onDone须要写一个接口如Active,而后把这个接口做为参数传入方法,重写onDone来对结果进行处理。
而kotlin中的回调不须要从新写一个接口。它能够直接把过程做为对象传入参数,以下:onDone是一个类型为(参数为User,返回值为Void的过程)。能够看到findUser方法的结尾调用了onDone,并把保存后的user做为参数传递进去了。调用findUser方法的时候,咱们就可使用lambda表达式写出对传入onDone的参数user对象的处理。
1 /* 2 * 查找指定用户名和密码的用户 3 * */ 4 fun findUser(userName:String,pwd:String, onDone:(User?) -> Unit){ 5 val query=JsonObject().put("name",userName).put("pwd",pwd) 6 mongoClient.find("jtest",query,{res-> 7 var user:User?=null 8 if (res.succeeded()){ 9 val result=res.result()[0] 10 if (!result.isEmpty){ 11 user=User(result.getString("name"),result.getString("pwd")) 12 } 13 } 14 onDone.invoke(user) 15 }) 16 }
val userDao = UserDao() val user = userDao.findUser(userName, pwd) { user -> if (user == null) { var resp = "用户名或密码输入错误!!" println(resp) } else { var resp = "登录成功!" println(resp) }
}
2018.7.27的再次更新:
加了注册功能,封装了一些方法,看起来更简洁了一些。对kotlin的异步有了更深的了解,回调函数能够传递,以下:
1 fun login(Param:JsonObject,onDone:(JsonObject)->Unit){ 2 LoginService().login(Param, {req-> 3 val request=req 4 onDone(req) 5 }) 6 } 7 8 //能够写成以下: 9 10 fun login(Param:JsonObject,onDone:(JsonObject)->Unit){ 11 LoginService().login(Param, onDone) 12 }
此外,若是反射要调用的函数里有回调,那么只须要先声明一个变量保存这个回调函数,再传入参数便可:
//回调函数 val call: (JsonObject) -> Unit = {response-> resp=response onDone(resp!!) } //获得类的引用M KClass<*> 类型 var M = Main.ins.controllerManager.controllers.get(actions[0]) //获得方法的引用A KFunction<*> 类型 var A = M?.methods?.get(actions[1]) //反射,这里把回调函数做为参数传入,不能直接把大括号写在里面 A?.javaMethod?.invoke(conIns, JsonObject(),call)