代码拉取完成,页面将自动刷新
基于 Kotlin + Netty 开发,为 Android 系统提供 Web Server 的功能,包括 Http、TCP、WebSocket
模块 | 最新版本 |
---|---|
android-server-core | |
android-server-converter-gson |
Gradle:
implementation 'com.safframework.server:android-server-core:<latest-version>'
implementation 'com.safframework.server:android-server-converter-gson:<latest-version>'
通过使用 Service 来启动一个 http 服务,它的 http 服务本身支持 rest 风格、支持跨域、cookies 等。
class HttpService : Service() {
private lateinit var androidServer: AndroidServer
override fun onCreate() {
super.onCreate()
startServer()
}
// 启动 Http 服务端
private fun startServer() {
androidServer = AndroidServer.Builder{
converter {
GsonConverter()
}
logProxy {
LogProxyImpl
}
}.build()
androidServer
.get("/hello") { _, response: Response ->
response.setBodyText("hello world")
}
.get("/sayHi/{name}") { request, response: Response ->
val name = request.param("name")
response.setBodyText("hi $name!")
}
.post("/uploadLog") { request, response: Response ->
val requestBody = request.content()
response.setBodyText(requestBody)
}
.get("/downloadFile") { request, response: Response ->
val fileName = "xxx.txt"
File("/sdcard/$fileName").takeIf { it.exists() }?.let {
response.sendFile(it.readBytes(),fileName,"application/octet-stream")
}?: response.setBodyText("no file found")
}
.get("/test") { _, response: Response ->
response.html(this,"test")
}
.fileUpload("/uploadFile") { request, response: Response -> // curl -v -F "file=@/Users/tony/1.png" 10.184.18.14:8080/uploadFile
val uploadFile = request.file("file")
val fileName = uploadFile.fileName
val f = File("/sdcard/$fileName")
val byteArray = uploadFile.content
f.writeBytes(byteArray)
response.setBodyText("upload success")
}
.filter("/sayHi/*", object : HttpFilter {
override fun before(request: Request): Boolean {
L.d("before....")
return true
}
override fun after(request: Request, response: Response) {
L.d("after....")
}
})
.start()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
androidServer.close()
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
测试:
curl -v 127.0.0.1:8080/hello
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /hello HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.50.1-DEV
> Accept: */*
>
< HTTP/1.1 200 OK
< server: monica
< content-type: text/plain
< content-length: 11
<
* Connection #0 to host 127.0.0.1 left intact
hello world
curl -v -d 测试 127.0.0.1:8080/uploadLog
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /uploadLog HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.50.1-DEV
> Accept: */*
> Content-Length: 6
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 6 out of 6 bytes
< HTTP/1.1 200 OK
< server: monica
< content-type: text/plain
< content-length: 6
<
* Connection #0 to host 127.0.0.1 left intact
测试
Socket 服务,AndroidServer 支持同一个端口同时提供 TCP/WebSocket 服务
class SocketService : Service() {
private lateinit var androidServer: AndroidServer
override fun onCreate() {
super.onCreate()
startServer()
}
// 启动 Socket 服务端
private fun startServer() {
androidServer = AndroidServer.Builder{
port {
8888
}
converter {
GsonConverter()
}
logProxy {
LogProxy
}
}.build()
androidServer
.socket("/ws", object: SocketListener<String> {
override fun onMessageResponseServer(msg: String, ChannelId: String) {
LogManager.d("SocketService","msg = $msg")
}
override fun onChannelConnect(channel: Channel) {
val insocket = channel.remoteAddress() as InetSocketAddress
val clientIP = insocket.address.hostAddress
LogManager.d("SocketService","connect client: $clientIP")
}
override fun onChannelDisConnect(channel: Channel) {
val ip = channel.remoteAddress().toString()
LogManager.d("SocketService","disconnect client: $ip")
}
})
.start()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
androidServer.close()
super.onDestroy()
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
Socket 服务可以使用 :https://github.com/fengzhizi715/NetDiagnose 进行测试
Wechat:fengzhizi715
Java与Android技术栈:每周更新推送原创技术文章,欢迎扫描下方的公众号二维码并关注,期待与您的共同成长和进步。
Copyright (C) 2017 - present, Tony Shen.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。