Remove readme

This commit is contained in:
2026-01-17 23:34:38 +08:00
parent e349eec63e
commit 1cf6c59e8a
2 files changed
-388

No files matched your search

-187
View File
@@ -1,187 +0,0 @@
# Kotlin cloudflare worker
纯Kotlin编写的库,可以在Cloudflare worker上运行Kotlin/JS
# 快速开始
## 配置
> 项目依赖于Kotlin协程库, 请确保协程库版本号大于`1.10.2`
```kotlin
plugins {
kotlin("multiplatform") version "2.2.21"
}
repositories {
mavenCentral()
maven("https://repo.maven.rtast.cn/releases")
}
```
```kotlin
// 最新版本请前往下方链接查看
// https://next.pkg.rtast.cn/#/releases/cn/rtast/kotlin-cfworker/core/
implementation("cn.rtast.kotlin-cfworker:core:1.0.2")
```
## Hello world程序
```kotlin
kotlin {
js(IR) {
nodejs {
outputModuleName = "kotlin-cloudflare-worker"
binaries.executable()
}
}
}
```
> Minimal hello world app
```kotlin
/**
* 不要修改这个函数的任何内容
*/
fun main() {
@Suppress("unused_expression")
val eventListener = EventListener { event ->
val dyn = event.asDynamic()
event.asDynamic().respondWith(handleRequest(dyn.request as Request))
Unit
}
js("addEventListener('fetch', eventListener)")
}
/**
* 这里是处理http请求的函数
*/
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
val server = WorkerApplication().apply {
route("/") {
respondText("Hello kotlin cloudflare worker")
}
}
return@promise server.handle(request)
}
```
> 在本地运行之前需要先安装wrangler
在项目根目录创建一个名为`wrangler.toml`的文件,然后将下面的内容复制进去并修改为你自己的信息
```toml
name = "kotlin-cloudflare-worker" # 可以是任何名字
account_id = "<your account id>"
workers_dev = false
preview_urls = false
compatibility_date = "2022-08-11"
main = "kotlin-cloudflare-worker.js" # 必须和`outputModuleName`一致
```
运行gradle任务编译出js `gradlew compileProductionExecutableKotlinJs`,
将wrangler.toml复制到 `build/compileSync/js/main/productionExecutable/kotlin`,
并且进入该目录下运行`wrangler dev`
## 部署
使用`wrangler deploy`来部署到cloudflare worker, 在此之前你需要先使用`wrangler login`来登录
# 注意事项
Cloudflare worker 使用V8引擎来驱动js脚本,线程模型为单线程,所有事件均由event loop(事件循环)驱动,在此之外的所有任务
都会被drop, 所以不要使用协程库中的launch或任何可以凭空创建出一个挂起作用域的函数来调用suspend函数, 取而代之的是你需要从
`handleRequest`方法中传播`CoroutineScope`(suspend), 就像下面这样
```kotlin
// 不要使用这种方法
val scope = CoroutineScope(Dispatcher.DEFAULT)
fun blockingFunction() {
scope.launch {
// 这里的代码永远不会被执行
}
}
// 使用下面的代码来正确的调用suspend函数
fun main() {
@Suppress("unused_expression")
val eventListener = EventListener { event ->
val dyn = event.asDynamic()
event.asDynamic().respondWith(handleRequest(dyn.request as Request))
Unit
}
js("addEventListener('fetch', eventListener)")
}
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
return Promise.resolve(Response("Hello"))
}
```
# Http 客户端
不要使用ktor来作为http客户端, 因为cloudflare worker不是一个标准的nodejs环境, 你需要使用 fetch
`cn.rtast.cfworker.client.fetch` 来发送http请求, 注意不是`window.fetch` `window.fetch`是浏览器API
# Websocket
仅支持Websocket服务器
> 使用类似ktor的语法注册websocket端点
```kotlin
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
val server = WorkerApplication().apply {
route("/") {
respondText("Hello kotlin cloudflare worker")
}
webSocket("/ws") {
onMessage {
println(it.readText())
}
onClose {
}
}
}
return@promise server.handle(request)
}
```
# ByteArray 和 ByteBuffer 转换
```kotlin
import cn.rtast.cfworker.util.toByteArray
import cn.rtast.cfworker.util.toArrayBuffer
val bb: ByteBuffer = ...
// 将ByteBuffer转换为ByteArray
val ba: ByteArray = bb.toByteArray()
// 将ByteArray转换为ByteBuffer
val bb2: ByteBuffer = ba.toArrayBuffer()
```
# CPU时间限制
cloudflare worker 免费版本限制处理每个请求的CPU时间为10ms(不包括IO等待时间), 如果你需要执行CPU密集型任务或需要更高的配额,
请考虑升级到Workers paid或使用JS来减少标准库和协程库的加载时间.
即使使用此库注册了超过15个api端点,并且都具备文件处理功能,每个请求占用的cpu时间平均值不超过10ms+-2ms,
在冷启动时处理首次请求时间会大幅增加,最高可达50ms,但worker仍然可以处理并返回请求.
![avg-cpu-time](./images/avg-cpu-time.png)
> 上图反应了过去24小时每个请求的平均cpu时间(P50)
# 已经使用此项目的实例
https://repo.maven.rtast.cn
-201
View File
@@ -1,201 +0,0 @@
# Kotlin cloudflare worker
A library to running kotlin/js on cloudflare worker.
<div style="display: block">
<a href="README.md">English</a>
<a href="README-zh.md">中文</a>
</div>
# Get started
## Setup
> `kotlinx.coroutines` is required
```kotlin
plugins {
kotlin("multiplatform") version "2.2.21"
}
repositories {
mavenCentral()
maven("https://repo.maven.rtast.cn/releases")
}
```
```kotlin
// to get latest version of this lib, go to
// https://next.pkg.rtast.cn/#/releases/cn/rtast/kotlin-cfworker/core/
implementation("cn.rtast.kotlin-cfworker:core:1.0.2")
```
## Run app
```kotlin
kotlin {
js(IR) {
nodejs {
outputModuleName = "kotlin-cloudflare-worker"
binaries.executable()
}
}
}
```
> Minimal hello world app
```kotlin
/**
* DO NOT EDIT THIS FUNCTION
*/
fun main() {
@Suppress("unused_expression")
val eventListener = EventListener { event ->
val dyn = event.asDynamic()
event.asDynamic().respondWith(handleRequest(dyn.request as Request))
Unit
}
js("addEventListener('fetch', eventListener)")
}
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
val server = WorkerApplication().apply {
route("/") {
respondText("Hello kotlin cloudflare worker")
}
}
return@promise server.handle(request)
}
```
> Before run worker locally, you need to install wrangler and login
First, create `wrangler.toml` in your root project and configure it
```toml
name = "kotlin-cloudflare-worker" # any name you want
account_id = "<your account id>"
workers_dev = false
preview_urls = false
compatibility_date = "2022-08-11"
main = "kotlin-cloudflare-worker.js" # Set this value same as `outputModuleName`
```
Then run gradle task `gradlew compileProductionExecutableKotlinJs`,
copy wrangler.toml into `build/compileSync/js/main/productionExecutable/kotlin`,
and run `wrangler dev` command in `build/compileSync/js/main/productionExecutable/kotlin`,
## Deploy
Run gradle task, copy wrangler.toml, but use `wrangler deploy` to deploy to cloudflare worker
# Note
JavaScript uses a single-threaded execution model. All asynchronous work is ultimately driven by the event loop (
including Kotlin coroutines on JS).
Therefore, DO NOT create a CoroutineScope(Dispatchers.Default) or launch CPU-bound coroutines, as there is no real
background thread on JS targets.
All coroutines run on same event loop thread, and all coroutines not in same event loop will be dropped.
Example:
```kotlin
// DO NOT DO THIS
val scope = CoroutineScope(Dispatcher.DEFAULT)
fun blockingFunction() {
scope.launch {
// this block will never execute
}
}
// Instead of do this
fun main() {
@Suppress("unused_expression")
val eventListener = EventListener { event ->
val dyn = event.asDynamic()
event.asDynamic().respondWith(handleRequest(dyn.request as Request))
Unit
}
js("addEventListener('fetch', eventListener)")
}
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
return Promise.resolve(Response("Hello"))
}
```
# Http client
Cloudflare worker is not a standard nodejs environment, do http requests must
use fetch api(not `window.fetch`, this is browser api), use `cn.rtast.cfworker.client.fetch` instead,
# Websocket
Only websocket server is supported
> ktor like expression
```kotlin
@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
val server = WorkerApplication().apply {
route("/") {
respondText("Hello kotlin cloudflare worker")
}
webSocket("/ws") {
onMessage {
println(it.readText())
}
onClose {
}
}
}
return@promise server.handle(request)
}
```
# ByteArray and ByteBuffer cast
Kotlin cloudflare worker provided api to mutual conversion,
```kotlin
import cn.rtast.cfworker.util.toByteArray
import cn.rtast.cfworker.util.toArrayBuffer
val bb: ByteBuffer = ...
// convert ByteBuffer to ByteArray
val ba: ByteArray = bb.toByteArray()
// convert ByteArray to ByteBuffer
val bb2: ByteBuffer = ba.toArrayBuffer()
```
# CPU Time limit
Cloudflare worker free tier have a limit of worker cpu limit (10ms, exclude IO waiting time), `kotlin cloudflare worker`
depends on `kotlin-stdlib` and `kotlinx.coroutines`, which are quite heavy*, When performing CPU-bound task,
please carefully consider whether to use JavaScript instead of Kotlin.
But it works for my maven repository, I registered over 15 api endpoints.
The avg cpu time for each endpoint does not exceed 10ms, but it may increase significantly during
cold start (Over 50-200ms, but still responsible)
![avg-cpu-time](./images/avg-cpu-time.png)
> This image shows last 24 hours avg cpu time, see `P50`
# Real instance
https://repo.maven.rtast.cn
> Yes, it the maven repository but built with kotlin/js with this lib