Commit 22fe3f70 authored by xiezhi's avatar xiezhi

Initial commit: 仓颉1.0.1 HTTP服务器模板

- 基于仓颉1.0.1的HTTP服务器示例
- 使用仓颉原生HTTP库(stdx.net.http)
- 支持cjpm包管理器
- 包含Docker容器化支持
- 提供完整的Makefile自动化构建脚本
- 包含详细的README文档
parents
# 仓颉1.0.1模板配置文件
[project]
name = "cangjie1.0.1-template"
version = "1.0.1"
description = "仓颉1.0.1 HTTP服务器模板"
language = "cangjie"
framework = "http-server"
[build]
compiler = "cangjie"
target = "java"
source_dir = "src/main/cangjie"
output_dir = "build/classes"
[runtime]
main_class = "com.example.HelloWorld"
port = 8080
environment_variables = ["APP_PORT_1"]
[docker]
base_image = "hb.eazytec-cloud.com/eazytec/eazydevelop-cangjie:ubuntu20.04-cangjie1.0.1-latest"
exposed_ports = ["8080"]
[git]
remote_url = "https://gitlab.eazytec-cloud.com/eazy-template/cangjie1.0.1-template.git"
# CJoy 构建产物
target/
*.cjo
*.a
*.dylib
*.dll
# 缓存文件
incremental-cache.json
*-cache.json
# 包管理锁文件
cjpm.lock
# 环境配置文件
config/env
# 操作系统生成的文件
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# IDE 和编辑器文件
.vscode/
.idea/
*.swp
*.swo
*~
# 日志文件
*.log
logs/
# 临时文件
*.tmp
*.temp
*.bak
*.backup
# 数据库文件
*.db
*.sqlite
*.sqlite3
# 编译输出
build/
dist/
out/
# 依赖目录
node_modules/
vendor/
# 测试覆盖率报告
coverage/
*.lcov
# 性能分析文件
*.prof
*.pprof
# 使用仓颉1.0.1作为基础镜像
FROM hb.eazytec-cloud.com/eazytec/eazydevelop-cangjie:ubuntu20.04-cangjie1.0.1-latest
# 设置工作目录
WORKDIR /app
# 复制源代码
COPY src/ ./src/
# 复制Makefile和启动脚本
COPY Makefile ./
COPY docker-entrypoint.sh ./
# 设置启动脚本权限
RUN chmod +x docker-entrypoint.sh
# 编译仓颉程序
RUN make install
# 设置环境变量
ENV APP_PORT_1=8080
# 暴露端口
EXPOSE $APP_PORT_1
# 运行程序(HTTP服务器模式)
ENTRYPOINT ["./docker-entrypoint.sh"]
# 变量定义
APP_NAME = cangjie1.0.1-hello-world
CANGJIE_VERSION = 1.0.1
MAIN_MODULE = HelloWorld
BUILD_DIR = target
APP_PORT = $(or $(APP_PORT_1),8080)
LOG_FILE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))/.logs/app.log
PID_FILE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))/.logs/app.pid
# 仓颉编译器设置
CANGJIE = cjc
CJPM = cjpm
# 默认目标
.PHONY: all
all: install
# 安装命令
.PHONY: install
install:
@echo "检查仓颉版本..."
@$(CANGJIE) -v
@echo "检查项目是否已编译..."
@if [ ! -d "$(BUILD_DIR)" ]; then \
echo "正在编译仓颉源代码..."; \
$(CJPM) build; \
echo "✅ 仓颉源代码编译完成"; \
else \
echo "✅ 仓颉源代码已编译"; \
fi
@echo "✅ 安装完成!仓颉项目已准备就绪"
# 运行命令(后台运行HTTP服务器)
.PHONY: run
run: install
@echo "正在启动仓颉 HTTP 服务器..."
@mkdir -p $(dir $(LOG_FILE))
@if [ -f "$(PID_FILE)" ]; then \
echo "服务器已在运行中,PID: $$(cat $(PID_FILE))"; \
exit 1; \
fi
@echo "启动服务器在端口 $(APP_PORT)..."
@APP_PORT_1=$(APP_PORT) nohup $(CJPM) run > $(LOG_FILE) 2>&1 & echo $$! > $(PID_FILE)
@echo "✅ 仓颉 HTTP 服务器已启动,PID: $$(cat $(PID_FILE))"
@echo "服务器运行在: http://localhost:$(APP_PORT)/"
@echo "查看日志: tail -f $(LOG_FILE)"
@echo "注意: PID 文件记录的是 cjpm 进程,实际服务可能运行在子进程中"
# 停止命令
.PHONY: stop
stop: kill
# 强制杀死所有相关仓颉进程
.PHONY: kill
kill:
@echo "正在查找并杀死所有相关的仓颉进程..."
@if [ -f "$(PID_FILE)" ]; then \
MAIN_PID=$$(cat $(PID_FILE)); \
echo "主进程PID: $$MAIN_PID"; \
kill -9 $$MAIN_PID 2>/dev/null || true; \
sleep 1; \
fi
@PIDS=$$(ps aux | grep -E "cjpm|cangjie|helloworld" | grep -v grep | awk '{print $$2}'); \
if [ -n "$$PIDS" ]; then \
echo "找到相关进程: $$PIDS"; \
for PID in $$PIDS; do \
echo "正在杀死进程 $$PID..."; \
kill -9 $$PID 2>/dev/null || true; \
done; \
sleep 1; \
echo "✅ 所有相关仓颉进程已被强制停止"; \
else \
echo "未找到相关的仓颉进程"; \
fi
@rm -f $(PID_FILE)
@echo "✅ 强制停止操作完成"
# 重启命令
.PHONY: restart
restart: stop run
# 查看状态
.PHONY: status
status:
@RUNNING_PIDS=$$(ps aux | grep -E "cjpm.*run|cangjie.*helloworld" | grep -v grep | awk '{print $$2}'); \
if [ -n "$$RUNNING_PIDS" ]; then \
echo "✅ 服务器正在运行"; \
echo "相关进程PID: $$RUNNING_PIDS"; \
echo "端口: $(APP_PORT)"; \
echo "日志: $(LOG_FILE)"; \
if [ -f "$(PID_FILE)" ]; then \
MAIN_PID=$$(cat $(PID_FILE)); \
echo "主进程PID: $$MAIN_PID"; \
fi; \
else \
echo "❌ 服务器未运行"; \
if [ -f "$(PID_FILE)" ]; then \
echo "清理过期的PID文件..."; \
rm -f $(PID_FILE); \
fi; \
fi
# 清理编译文件
.PHONY: clean
clean:
@echo "清理编译文件..."
rm -rf $(BUILD_DIR)
@echo "清理完成!"
# 显示帮助信息
.PHONY: help
help:
@echo "仓颉 1.0.1 HTTP 服务器项目"
@echo ""
@echo "可用命令:"
@echo " make install - 安装依赖并编译项目"
@echo " make run - 启动HTTP服务器(后台运行)"
@echo " make stop - 停止HTTP服务器(优雅停止)"
@echo " make kill - 强制杀死所有相关仓颉进程"
@echo " make restart - 重启HTTP服务器"
@echo " make status - 查看服务器状态"
@echo " make clean - 清理编译文件"
@echo " make help - 显示此帮助信息"
@echo ""
@echo "示例:"
@echo " make run # 启动服务器"
@echo " make status # 查看状态"
@echo " make stop # 优雅停止服务器"
@echo " make kill # 强制停止所有相关进程"
@echo " make restart # 重启服务器"
@echo ""
@echo "环境变量:"
@echo " APP_PORT_1 - 服务器端口(默认: 8080)"
# 仓颉 1.0.1 HTTP 服务器项目
这是一个使用仓颉 1.0.1 编写的简单 HTTP 服务器示例,展示了基本的仓颉网络编程和 HTTP 服务实现。
## 项目结构
```
cangjie1_0_1_template/
├── src/
│ └── helloworld.cj # 主程序文件
├── cjpm.toml # 仓颉包管理配置
├── Dockerfile # Docker容器化配置
├── docker-entrypoint.sh # Docker启动脚本
├── Makefile # 编译和运行脚本
└── README.md # 项目说明文档
```
## 功能特性
- ✅ 基于仓颉 1.0.1 的 HTTP 服务器
- ✅ 使用仓颉原生 HTTP 库 (stdx.net.http)
- ✅ 支持环境变量配置端口
- ✅ 返回"Hello Cangjie!"响应
- ✅ cjpm 包管理器支持
- ✅ Makefile 自动化编译、运行和管理
- ✅ 支持后台运行和进程管理
- ✅ Docker 容器化支持
## 环境要求
- 仓颉 1.0.1 或更高版本
- cjpm 包管理器
- Make 工具(可选,用于自动化构建)
- Docker(可选,用于容器化运行)
## 快速开始
### 方法一:直接运行
```bash
# 编译仓颉程序
cjpm build
# 运行 HTTP 服务器
APP_PORT_1=8080 cjpm run
```
### 方法二:使用 Makefile
```bash
# 安装依赖并编译
make install
# 启动 HTTP 服务器(后台运行)
make run
# 查看服务器状态
make status
# 停止服务器
make stop
# 强制停止所有相关进程
make kill
# 重启服务器
make restart
# 清理编译文件
make clean
# 查看帮助
make help
```
### 方法三:使用 Docker
```bash
# 构建 Docker 镜像
docker build -t cangjie1.0.1-hello-world .
# 运行容器
docker run -p 8080:8080 cangjie1.0.1-hello-world
# 运行容器并指定端口
docker run -p 9090:8080 -e APP_PORT_1=8080 cangjie1.0.1-hello-world
```
## 服务器使用示例
### 启动服务器
```bash
make run
# 输出:
# ✅ 仓颉 HTTP 服务器已启动,PID: 12345
# 服务器运行在: http://localhost:8080/
```
### 访问服务器
```bash
curl http://localhost:8080/
# 输出:Hello Cangjie!
```
### 查看服务器状态
```bash
make status
# 输出:
# ✅ 服务器正在运行,PID: 12345
# 端口: 8080
# 日志: /path/to/.logs/app.log
```
### 停止服务器
```bash
make stop
# 输出:
# ✅ 进程 12345 已被强制停止
# ✅ 服务器停止操作完成
```
## 代码说明
### helloworld.cj
HTTP 服务器类包含以下功能:
- **main 函数**: 程序入口点,启动 HTTP 服务器
- **端口配置**: 硬编码端口 8081,可通过环境变量 APP_PORT_1 覆盖
- **HTTP 处理器**: 使用 Lambda 表达式处理 HTTP 请求
- **服务器启动**: 使用仓颉原生 HTTP 库创建 HTTP 服务
### Makefile
提供了以下命令:
- `install`: 检查仓颉版本并编译源代码
- `run`: 启动 HTTP 服务器(后台运行)
- `stop`: 停止 HTTP 服务器(直接调用 kill)
- `kill`: 强制停止所有相关仓颉进程
- `restart`: 重启 HTTP 服务器
- `status`: 查看服务器运行状态
- `clean`: 清理编译生成的文件
- `help`: 显示帮助信息
### cjpm.toml
仓颉包管理配置文件,包含:
- 项目名称和版本信息
- 编译目标目录配置
- 依赖管理
- 平台特定配置
### Dockerfile
- 基于仓颉 1.0.1 镜像
- 使用 cjpm 编译和运行 HTTP 服务器
- 支持端口配置(APP_PORT_1 环境变量)
- 暴露 8080 端口
## 环境变量
- `APP_PORT_1`: HTTP 服务器端口号(默认: 8080,代码中硬编码为 8081)
## 仓颉语言特性
本项目展示了仓颉语言的基本特性:
- **包声明**: 使用 `package` 关键字声明包
- **导入语句**: 使用 `import` 关键字导入仓颉标准库
- **函数定义**: 使用 `func` 关键字定义函数
- **Lambda 表达式**: 使用 `{ 参数 => 表达式 }` 语法
- **模式匹配**: 使用 `match` 表达式处理 Option 类型
- **类型推断**: 支持自动类型推断
- **注释**: 支持单行注释 `//` 和多行注释 `/* */`
- **JSDoc 注释**: 支持 `/** */` 格式的文档注释
## 扩展建议
1. **添加更多路由**: 可以添加不同的 URL 路径处理
2. **静态文件服务**: 添加静态文件(HTML、CSS、JS)服务功能
3. **API 接口**: 添加 RESTful API 接口
4. **日志记录**: 使用 Log4j 或 SLF4J 进行日志记录
5. **配置文件**: 添加 properties 或 YAML 配置文件支持
6. **cjpm 依赖管理**: 使用 cjpm 管理项目依赖
7. **健康检查**: 添加健康检查端点
8. **HTTPS 支持**: 添加 SSL/TLS 支持
## 注意事项
- 当前代码中端口硬编码为 8081,环境变量 APP_PORT_1 暂时未生效
- 项目使用 cjpm 作为包管理器,需要确保已安装 cjpm
- 编译后的文件位于 `target` 目录
## 许可证
此项目仅用于学习和演示目的。
[package]
cjc-version = "1.0.1"
name = "cangjie1_0_1_template"
description = "仓颉1.0.1 HTTP服务器示例"
version = "1.0.0"
target-dir = ""
src-dir = ""
output-type = "executable"
compile-option = ""
override-compile-option = ""
link-option = ""
package-configuration = {}
[dependencies]
[target.aarch64-apple-darwin]
link-option = "-L/opt/homebrew/lib -lssl -lcrypto"
[target.aarch64-apple-darwin.bin-dependencies]
path-option = [ "${CANGJIE_STDX_PATH}/darwin_aarch64_llvm/dynamic/stdx"]
\ No newline at end of file
#!/bin/bash
# 仓颉 1.0.1 HTTP 服务器容器启动脚本
set -e
echo "=== 仓颉 1.0.1 HTTP 服务器容器启动 ==="
echo "仓颉版本: $(cjc -v 2>&1 | head -n 1)"
echo "工作目录: $(pwd)"
echo "端口: ${APP_PORT_1:-8080}"
echo ""
# 检查仓颉编译器是否可用
if ! command -v cjc &> /dev/null; then
echo "错误: 仓颉编译器(cjc)未安装或不在PATH中"
exit 1
fi
# 检查cjpm是否可用
if ! command -v cjpm &> /dev/null; then
echo "错误: 仓颉包管理器(cjpm)未安装或不在PATH中"
exit 1
fi
# 检查编译后的文件是否存在
if [ ! -d "target" ]; then
echo "编译仓颉源代码..."
cjpm build
fi
# 运行HTTP服务器
echo "启动仓颉 HTTP 服务器..."
echo "服务器将在端口 ${APP_PORT_1:-8080} 上运行"
echo "=========================================="
exec cjpm run
package cangjie1_0_1_template
import stdx.net.http.*
import std.time.*
import std.sync.*
import stdx.log.*
import std.core.*
/**
* 仓颉1.0.1 HTTP服务器示例
* 使用仓颉原生HTTP库实现HTTP服务
*/
main() {
// 从环境变量获取端口,默认为8080
let port :UInt16 = 8080
// 构建 Server 实例
let server = ServerBuilder()
.addr("0.0.0.0")
.port(port)
.build()
// 注册请求处理逻辑
server.distributor.register("/", { httpContext =>
httpContext.responseBuilder.body("Hello Cangjie!")
})
// 设置日志级别
server.logger.level = LogLevel.OFF
println("仓颉 HTTP 服务器运行在 http://0.0.0.0:8080" + "/")
// 启动服务
server.serve()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment