我想常常运用Kotlin写项目的人应该都对Ktor这个结构不陌生,它严格意义上不仅仅是个网络结构,而是一个能够创立异步,高性能和轻量级的Web服务结构,简单的来说它既能写服务端也能写客户端,之前我也用过Ktor写过一个客户端小项目,这次也刚好测验下如何用Ktor来写服务端代码,并在客户端对它建议恳求

服务端

1.创立项目

首要是要创立一个Ktor的服务端项目,创立的办法有多种,在Ktor的官网上有介绍,第一种是针对Intellij运用的是Ultimate的用户,能够直接在编辑器里边直接New Project,然后挑选创立Ktor项目就好了

从服务端到客户端,一次Ktor的跨端实践

第二种办法是针对Intellij运用社区版别的用户,能够去start.ktor.io地址挑选对应插件,然后创立项目,接着项目就会经过浏览器下载到你的本地,打开即可,这也是我挑选的办法,一会还会详细说

从服务端到客户端,一次Ktor的跨端实践

第三种办法是手动添加装备,先自己创立个项目,然后经过Ktor供给的装备代码装备到你的项目中去,Ktor总共供给了Grovvy,Kotlin和Maven三种办法的装备代码供用户挑选

从服务端到客户端,一次Ktor的跨端实践

接下来咱们就运用第二种办法来创立项目,首要进入start.ktor.io,会先看到一个编辑框,需求先输入你的服务端项目的名字,这个随意写就好

从服务端到客户端,一次Ktor的跨端实践

然后点击Add plugins按钮进入下一个页面,也会看到一个输入框以及一个列表,列表里边是多种多样服务端插件,我选取几种插件,然后点击Generate project按钮,咱们的项目包就下载到了咱们的本地了

从服务端到客户端,一次Ktor的跨端实践
从服务端到客户端,一次Ktor的跨端实践

解压然后在IDE中打开,咱们的初始项目就完成了

2.项目结构

当咱们打开方才下载完成的项目的时分,咱们会看到全体项目结构呈现的会是下面这个样子

从服务端到客户端,一次Ktor的跨端实践

build.gradle.kts都很了解了,整个项目的一个装备文件,咱们刚刚挑选的插件的依靠,就在build.gralde.kts里边生成了,详细代码如下

从服务端到客户端,一次Ktor的跨端实践
  • ktor-server-core:供给核心的Ktor组件
  • ktor-server-host-common:查不到详细介绍,看名字应该是与装备域名有关
  • ktor-server-status-pages:用来处理各种网络反常
  • ktor-server-default-headers:用来给http的response添加头信息
  • ktor-server-netty:供给一个Netty引擎
  • ktor-server-content-negotiationktor-serialization-kotlinx-json:能够便利的将Kotlin的目标转换成序列化方式,常见的便是json
  • logback-classic:SLF4J的插件,让你能够清晰的在控制台看到格局化的log输出

resources文件夹下放的是一些装备文件,比方项目生成的这个logback.xml,首要用来界说一个log输出的结构,里边的代码是这样的

从服务端到客户端,一次Ktor的跨端实践

刚开始咱们运用默许的格局就好,等熟练了能够自己去自界说,除了logback.xml文件,还能够放置一些资源文件,比方一些服务端的图片资源就能够在这儿添加,稍后咱们就会测验一下,然后便是源码这儿,首要是Application.kt文件,这是项目的主文件,里边是项目的进口函数以及一些项目的模块装备

从服务端到客户端,一次Ktor的跨端实践

main函数里边咱们能够设置服务器的端口以及ip,以及一些模块功用,这些功用都在module函数里边,configureHttp()函数的功用是装备一些Http信息,比方每次发送出去的response自带的一些头信息就在这儿装备,这些代码在Http.kt文件里边

从服务端到客户端,一次Ktor的跨端实践

configureSerialization函数界说在Serialization.kt文件里边,首要功用便是装置ContentNegotiation以及json序列化

从服务端到客户端,一次Ktor的跨端实践

configureRouting函数界说在Routing.kt文件里边,在这个函数里边就能够写一些接口,状态码,状态码对应的message以及装备一些资源信息,比方图片,从下下来的项目里咱们能够看到在这个函数里边现已有一个案例接口在里边了

从服务端到客户端,一次Ktor的跨端实践

这是一个get恳求,意思是直接拜访咱们的接口ip加端口号就能回来Hello world!字符串,咱们来测验一下这个恳求,来运转一下Application.kt文件里边的main函数

从服务端到客户端,一次Ktor的跨端实践

等运转成功之后,你会在控制台里边看到下面这些日志,阐明你本地现已敞开了一个服务,地址是http://0.0.0.0:8080

从服务端到客户端,一次Ktor的跨端实践

当咱们在浏览器里边输入这个地址的时分,就会看到浏览器的界面上就输出了一行Hello world!的信息,也便是项目傍边那个get恳求

从服务端到客户端,一次Ktor的跨端实践

就这样一个最根本的服务端部分的代码就写完了,很简单是不是,现在咱们就来测验下写一个接口,这个接口便是获取一个图片信息的数组

3.第一个接口

既然是要回来一个图片信息的数组,那么首要需求界说一个图片信息的数据类,咱们把它命名为SinglePhoto.kt,里边有这个图片的id,描绘,以及这个图片的地址

从服务端到客户端,一次Ktor的跨端实践

然后咱们再界说一个PhotoSource.kt文件,里边是获取图片数组的操作,比方从数据库查询等,数据库部分等我学会了再写,这儿先固定回来一个数组,函数名叫queryPhotoList

从服务端到客户端,一次Ktor的跨端实践

图片的链接咱们一会再添加,然后到Routing.kt文件里边,在那里的get恳求下面再添加一个get恳求,途径部分咱们写上/queryPhotos,lambda表达式里边运用ApplicationCall目标的respond函数来回来一个图片信息的数组

从服务端到客户端,一次Ktor的跨端实践

此刻咱们再运转一遍代码,在浏览器里边输入http://0.0.0.0:8080/queryPhotos 地址,就得到了咱们的图片信息数组的json字符串了

从服务端到客户端,一次Ktor的跨端实践

接下来便是装备图片的链接了,之前说过在resources文件夹下能够装备图片资源,那么咱们找几张图放到resources文件夹底下

从服务端到客户端,一次Ktor的跨端实践

接着咱们将这些图片代表的链接添加到queryPhotoList的回来数据里边

从服务端到客户端,一次Ktor的跨端实践

这个时分咱们再从头运转一遍程序,在浏览器里边从头拜访一下http://0.0.0.0:8080/queryPhotos 地址,回来的json字符串里边就带有图片链接了

从服务端到客户端,一次Ktor的跨端实践

别的咱们发现现在接口回来的数据是一个list,而比较标准的回来数据的格局往往都是key-value方式,也便是咱们需求将回来的list包在一个object里边,怎么做呢?很简单,直接respond一个map就好了

从服务端到客户端,一次Ktor的跨端实践

现在咱们再从头运转一遍程序,接口回来的数据便是一个object了

从服务端到客户端,一次Ktor的跨端实践

咱们随便找一个链接复制出来放在浏览器里边,来验证下能不能打开咱们的图片,成果看到的景象是浏览器回来的是404,找不到这个图片链接,阐明咱们还少了点装备

从服务端到客户端,一次Ktor的跨端实践

少了什么装备呢,便是除了添加完图片资源之外,也必须在routing函数里边设置一下静态资源的途径,运用staticResources函数设置,这个函数第一个参数是remotePath,我觉得应该表明的是其他服务器的地址,这儿暂时为空,第二个参数是basePackage,也便是图片资源地点的包名,咱们目前图片直接是在resources的根目录,所以包名也是空,最终代码如下

从服务端到客户端,一次Ktor的跨端实践

这儿需求注意的是我这个项目的ktor版别运用的是2.3.3,假如低于这个版别的话staticResources函数是会报红的,原因是这个函数是2.3.3版别新出来的,老版别运用的是另一种设置静态资源的办法,代码如下

从服务端到客户端,一次Ktor的跨端实践

相同的resources里边也是传入图片的包名,没有就传空字符串,新老版别ktor在这儿是存在差异的,这个时分咱们再运转一遍程序,在浏览器里边从头拜访一遍之前的图片链接,咱们的图片就打开了

从服务端到客户端,一次Ktor的跨端实践

而在实在的项目傍边,图片的目录层级分很多种,有的还是依照模块来划分的,这个时分咱们不得不将图片资源添加到不同的目录层级中,这个时分咱们的图片资源就需求一个basePackage了,咱们将这个basePackage命名为base,然后在base底下再新建两个包名,分别是onetwo,将一部分图片挪入one里边,另一部分图片挪入two里边,作用如下

从服务端到客户端,一次Ktor的跨端实践

图片的途径变了,那么回来值里边的图片链接也要跟着一起改变

从服务端到客户端,一次Ktor的跨端实践

能够看到图片地址里边并没有将根目录base写进去,而是将二级目录one或许two写进去了,可是虽然图片链接里边没有声明根目录,咱们在staticResources函数里边需求将base设置到basePackage参数里边去,不然依然会报404

从服务端到客户端,一次Ktor的跨端实践

这个时分咱们再运转一遍程序,将最新的图片链接输入到浏览器的地址栏里边,咱们的图片依然成功地加载出来了

从服务端到客户端,一次Ktor的跨端实践

现在咱们来写一个简单的Compose desktop的小demo,功用很简单,便是恳求一下queryPhotos接口,并将回来的数据展示在界面上

客户端

1.创立项目

Compose desktop如何创立项目就不详细介绍了,不清楚的能够自行ChatGPT,先看下gradle里边都用到了哪些ktor插件

从服务端到客户端,一次Ktor的跨端实践

能够看到与之前的服务端装备相比,除掉服务端特定的插件之外,根本运用的东西相同,一个是server版别,一个是client版别的,这儿需求说到的是,我这边客户端运用的ktor版别是2.2.3,而服务端用的是2.3.3,所以咱们做的时分也不用去特意将两头的ktor版别弄成相同,究竟我看ktor官网里边也没有特别阐明这一点,然后便是装备你的HttpClient

从服务端到客户端,一次Ktor的跨端实践

HttpClient的装备也很简单,首要传入的CIO是一种引擎,由于Ktor能够运用在不同的渠道上,所以为了兼容各个渠道的特性,运用的引擎也是因渠道而异,下面是一张渠道与引擎的对应表

从服务端到客户端,一次Ktor的跨端实践

除了引擎之外,接下去便是装置各种插件,办法便是调用install函数,这儿装置的是DefaultRequest插件,日志插件以及ContentNegotiation插件,要运用什么插件依照自己的项目需求来装置,在DefaultRequest里边,装备的便是咱们恳求的协议以及地址,这儿值得注意的是假如你的服务端地址是ip的话,一定要将端口别的拿出来设置,假如将你的端口与ip同时作为host的话,那么建议恳求的时分就会报UnresolvedAddressException

从服务端到客户端,一次Ktor的跨端实践

然后便是界说咱们的数据模型,这个模型跟服务端的根本相同所以能够直接拿过来用

从服务端到客户端,一次Ktor的跨端实践

最后便是恳求接口部分,新建一个文件PhotoListService.kt,在里边写上一个getImageList函数用来对接咱们queryPhotos接口

从服务端到客户端,一次Ktor的跨端实践

到这儿一切客户端的网络层代码就写完了,剩下的便是在界面上调用getImageList函数将得到的数据烘托到界面上,咱们直接更改案例代码中的App函数,在里边放置一个LazyColumn组件

从服务端到客户端,一次Ktor的跨端实践

由于getImageList函数是一个挂起函数,所以需求将它放在一个协程作用域里边,别的由于Compose desktop无法运用图片加载结构coil,由于它目前只支撑移动端,所以这儿别的找了一个支撑Desktop版别的图片加载结构

从服务端到客户端,一次Ktor的跨端实践

客户端部分的一切代码也都开发完毕了,让咱们运转一下看看作用

从服务端到客户端,一次Ktor的跨端实践

总结

至此,咱们第一次运用ktor同时进行服务端与客户端的开发就完成了,能够看到全体的项目结构都不是很复杂,根本看一下官方文档自己就能写了,虽然代码傍边还有很多设计上的缺乏,比方服务端回来的数据最外层没有用code与message包起来,获取的数据也没有从数据库中加载出来,但这些都会在今后渐渐完善起来,从全体上来看,关于一个前端人来说,今后在开发过程中能够自己写服务端代码去调试自己的界面,等到后端同学供给接口之后再无缝切换,而不是经过写假数据来调试界面,这样既耽误时间,也有可能由于忘记删掉假数据而形成问题。