{"id":19237540,"url":"https://github.com/fengzhizi715/androidserver","last_synced_at":"2025-08-21T02:31:54.408Z","repository":{"id":45520531,"uuid":"248783728","full_name":"fengzhizi715/AndroidServer","owner":"fengzhizi715","description":"基于 Kotlin + Netty 开发，为 Android App 提供 Server 的功能，包括 Http、TCP、WebSocket 服务","archived":false,"fork":false,"pushed_at":"2022-02-16T11:58:30.000Z","size":346,"stargazers_count":188,"open_issues_count":8,"forks_count":39,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-08T02:01:43.552Z","etag":null,"topics":["android","android-server","http-server","kotlin-android","socket","tcp-server","websocket"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fengzhizi715.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-20T15:03:14.000Z","updated_at":"2025-03-23T02:05:03.000Z","dependencies_parsed_at":"2022-07-16T01:30:32.687Z","dependency_job_id":null,"html_url":"https://github.com/fengzhizi715/AndroidServer","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/fengzhizi715/AndroidServer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengzhizi715%2FAndroidServer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengzhizi715%2FAndroidServer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengzhizi715%2FAndroidServer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengzhizi715%2FAndroidServer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fengzhizi715","download_url":"https://codeload.github.com/fengzhizi715/AndroidServer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengzhizi715%2FAndroidServer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271416930,"owners_count":24755994,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-server","http-server","kotlin-android","socket","tcp-server","websocket"],"created_at":"2024-11-09T16:27:17.159Z","updated_at":"2025-08-21T02:31:54.019Z","avatar_url":"https://github.com/fengzhizi715.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AndroidServer\n\n[![@Tony沈哲 on weibo](https://img.shields.io/badge/weibo-%40Tony%E6%B2%88%E5%93%B2-blue.svg)](http://www.weibo.com/fengzhizi715)\n[![License](https://img.shields.io/badge/license-Apache%202-lightgrey.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n[![](https://jitpack.io/v/fengzhizi715/AndroidServer.svg)](https://jitpack.io/#fengzhizi715/AndroidServer)\n\n基于 Kotlin + Netty 开发，为 Android App 提供 Server 的功能，包括 Http、TCP、WebSocket 服务\n\n# Feature:\n\n* 支持 Http、TCP、WebSocket 服务\n* 支持 Rest 风格的 API、文件上传、下载\n* 支持加载静态网页\n* Http 的路由表、全局的 HttpFilter 均采用字典树(Tried Tree)实现\n* 日志隔离，开发者可以使用自己的日志库\n* core 模块只依赖 netty-all，不依赖其他第三方库\n\n# 最新版本\n\n模块|最新版本\n---|:-------------:\nandroid-server-core|[![](https://jitpack.io/v/fengzhizi715/AndroidServer.svg)](https://jitpack.io/#fengzhizi715/AndroidServer)\nandroid-server-converter-gson|[![](https://jitpack.io/v/fengzhizi715/AndroidServer.svg)](https://jitpack.io/#fengzhizi715/AndroidServer)\n\n# 下载安装\n\n将它添加到项目的 root build.gradle 中：\n\n```groovy\n\tallprojects {\n\t\trepositories {\n\t\t\t...\n\t\t\tmaven { url 'https://jitpack.io' }\n\t\t}\n\t}\n```\n\nGradle:\n\n```groovy\nimplementation 'com.github.fengzhizi715.AndroidServer:core:\u003clatest-version\u003e'\n```\n\n```groovy\nimplementation 'com.github.fengzhizi715.AndroidServer:gson:\u003clatest-version\u003e'\n```\n\n# Usage:\n\n## 搭建 Http 服务\n\nAndroidServer 的 http 服务本身支持 rest 风格、支持跨域、cookies 等。\n\n```kotlin\nfun startHttpServer(context:Context, androidServer:AndroidServer) {\n\n    androidServer\n        .get(\"/hello\") { _, response: Response -\u003e\n            response.setBodyText(\"hello world\")\n        }\n        .get(\"/sayHi/{name}\") { request, response: Response -\u003e\n            val name = request.param(\"name\")\n            response.setBodyText(\"hi $name!\")\n        }\n        .post(\"/uploadLog\") { request, response: Response -\u003e\n            val requestBody = request.content()\n            response.setBodyText(requestBody)\n        }\n        .get(\"/downloadFile\") { request, response: Response -\u003e\n            val fileName = \"xxx.txt\"\n            File(\"/sdcard/$fileName\").takeIf { it.exists() }?.let {\n                response.sendFile(it.readBytes(),fileName,\"application/octet-stream\")\n            }?: response.setBodyText(\"no file found\")\n        }\n        .get(\"/test\") { _, response: Response -\u003e\n            response.html(context,\"test\")\n        }\n        .fileUpload(\"/uploadFile\") { request, response: Response -\u003e // curl -v -F \"file=@/Users/tony/1.png\" 10.184.18.14:8080/uploadFile\n\n            val uploadFile = request.file(\"file\")\n            val fileName = uploadFile.fileName\n            val f = File(\"/sdcard/$fileName\")\n            val byteArray = uploadFile.content\n            f.writeBytes(byteArray)\n\n            response.setBodyText(\"upload success\")\n        }\n        .filter(\"/sayHi/*\", object : HttpFilter {\n            override fun before(request: Request): Boolean {\n                LogManager.d(\"HttpService\",\"before....\")\n                return true\n            }\n\n            override fun after(request: Request, response: Response) {\n                LogManager.d(\"HttpService\",\"after....\")\n            }\n\n        })\n        .start()\n}\n```\n\n测试：\n\n```\ncurl -v 127.0.0.1:8080/hello\n*   Trying 127.0.0.1...\n* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)\n\u003e GET /hello HTTP/1.1\n\u003e Host: 127.0.0.1:8080\n\u003e User-Agent: curl/7.50.1-DEV\n\u003e Accept: */*\n\u003e\n\u003c HTTP/1.1 200 OK\n\u003c server: monica\n\u003c content-type: text/plain\n\u003c content-length: 11\n\u003c\n* Connection #0 to host 127.0.0.1 left intact\nhello world\n```\n\n```\ncurl -v -d 测试 127.0.0.1:8080/uploadLog\n*   Trying 127.0.0.1...\n* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)\n\u003e POST /uploadLog HTTP/1.1\n\u003e Host: 127.0.0.1:8080\n\u003e User-Agent: curl/7.50.1-DEV\n\u003e Accept: */*\n\u003e Content-Length: 6\n\u003e Content-Type: application/x-www-form-urlencoded\n\u003e\n* upload completely sent off: 6 out of 6 bytes\n\u003c HTTP/1.1 200 OK\n\u003c server: monica\n\u003c content-type: text/plain\n\u003c content-length: 6\n\u003c\n* Connection #0 to host 127.0.0.1 left intact\n测试\n```\n\n## 搭建 WebSocket 服务\n\nAndroidServer 支持提供 WebSocket 服务\n\n```kotlin\nfun startWebSocketServer(androidServer:AndroidServer) {\n    androidServer\n        .websocket(\"/ws\",object : SocketListener\u003cString\u003e{\n            override fun onMessageResponseServer(msg: String, ChannelId: String) {\n                LogManager.d(\"WebSocketService\",\"msg = $msg\")\n            }\n\n            override fun onChannelConnect(channel: Channel) {\n                val insocket = channel.remoteAddress() as InetSocketAddress\n                val clientIP = insocket.address.hostAddress\n                LogManager.d(\"WebSocketService\",\"connect client: $clientIP\")\n\n            }\n\n            override fun onChannelDisConnect(channel: Channel) {\n                val ip = channel.remoteAddress().toString()\n                LogManager.d(\"WebSocketService\",\"disconnect client: $ip\")\n            }\n\n        })\n        .start()\n}\n```\n\n测试：\n\n```\ncurl -v \\\n     --include \\\n     --no-buffer \\\n     --header \"Connection: Upgrade\" \\\n     --header \"Upgrade: websocket\" \\\n     --header \"Host: echo.websocket.org\" \\\n     --header \"Origin: https://echo.websocket.org\" \\\n     --header \"Sec-WebSocket-Key: NVwjmQUcWCenfWu98asDmg==\" \\\n     --header \"Sec-WebSocket-Version: 13\" \\\n     http://127.0.0.1:8080/ws\n```\n\n```\nGET /ws HTTP/1.1\nHost: echo.websocket.org\nUser-Agent: curl/7.67.0\nAccept: */*\nConnection: Upgrade\nUpgrade: websocket\nOrigin: https://echo.websocket.org\nSec-WebSocket-Key: NVwjmQUcWCenfWu98asDmg==\nSec-WebSocket-Version: 13\n```\n\n```\nHTTP/1.1 101 Switching Protocols\nupgrade: websocket\nconnection: upgrade\nsec-websocket-accept: oPhRcOTYgRvrC0D+cTPcN3XYC1k=\n```\n\n\u003e Socket/WebSocket 服务可以使用 ：https://github.com/fengzhizi715/NetDiagnose 进行测试。\n上述 websocket 服务默认的 endpoint：ws://ip:port/ws\n\n\n## 搭建 Socket 服务\n\nAndroidServer 支持单独提供 Socket 服务，也支持一个端口同时提供 Socket/WebSocket 服务。\n\n使用 androidServer 的 socketAndWS()，同时提供 Socket/WebSocket 服务：\n\n```kotlin\nfun startSocketServer(androidServer:AndroidServer) {\n    androidServer\n        .socketAndWS(\"/ws\", object: SocketListener\u003cString\u003e {\n            override fun onMessageResponseServer(msg: String, ChannelId: String) {\n                LogManager.d(\"SocketService\",\"msg = $msg\")\n            }\n\n            override fun onChannelConnect(channel: Channel) {\n                val insocket = channel.remoteAddress() as InetSocketAddress\n                val clientIP = insocket.address.hostAddress\n                LogManager.d(\"SocketService\",\"connect client: $clientIP\")\n\n            }\n\n            override fun onChannelDisConnect(channel: Channel) {\n                val ip = channel.remoteAddress().toString()\n                LogManager.d(\"SocketService\",\"disconnect client: $ip\")\n            }\n\n        })\n        .start()\n}\n```\n\nandroidServer 的 socket() 单独提供 Socket 服务。\n\n# TODO List：\n\n* 提供默认的 TCP 服务\n* 支持 Https\n* 反向代理\n* 支持 HTTP/2\n\n\n联系方式\n===\n\nWechat：fengzhizi715\n\n\n\u003e Java与Android技术栈：每周更新推送原创技术文章，欢迎扫描下方的公众号二维码并关注，期待与您的共同成长和进步。\n\n![](https://github.com/fengzhizi715/NetDiscovery/blob/master/images/gzh.jpeg)\n\n\nChangeLog\n===\n[版本更新记录](CHANGELOG.md)\n\nLicense\n-------\n\n    Copyright (C) 2017 - present, Tony Shen.\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffengzhizi715%2Fandroidserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffengzhizi715%2Fandroidserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffengzhizi715%2Fandroidserver/lists"}