# MM_OS 服务端架构

[![npm version](https://badge.fury.io/js/mm_os.svg)](https://badge.fury.io/js/mm_os)
[![npm downloads](https://img.shields.io/npm/dm/mm_os.svg)](https://www.npmjs.com/package/mm_os)
[![License](https://img.shields.io/npm/l/mm_os.svg)](https://gitee.com/qiuwenwu91/mm_os/blob/master/LICENSE)

## 项目简介

MM_OS 是一个轻量级的服务端架构，提供了完整的服务端开发框架，包括 Web、WebSocket、MQTT、Socket 等多种通信协议支持，以及丰富的组件和模块。

**适用场景：**
- **网站建设**：快速构建企业网站、电商平台、内容管理系统
- **小程序**：微信小程序、支付宝小程序等小程序后台服务
- **AI 应用**：AI 接口服务、智能助手、机器学习推理服务
- **物联网 (IOT/AIOT)**：物联网设备管理、传感器数据采集、智能硬件控制
- **游戏服务端**：中小型游戏服务端、实时对战游戏、游戏后台管理

支持 **AI、GAME、IOT、AIOT、游戏、物联网、小程序、网站建设** 等多种应用场景。

## 核心功能

- **多协议支持**：Web、WebSocket、MQTT、Socket
- **模块化设计**：应用、模组、中间件、通知器、消息发送器、广播器
- **基础设施**：数据库、缓存、日志、文件管理
- **事件驱动**：基于事件总线的异步处理
- **插件系统**：支持功能扩展

## 设计理念：配置与逻辑分离

MM_OS 框架的核心设计原则是 **配置与逻辑分离**。无论是 `core` 核心模块还是 `com` 公共组件，每个功能模块都遵循统一的结构：

### 模块组成

每个模块由以下文件组成：

| 文件类型 | 文件名 | 作用 |
|----------|--------|------|
| **配置文件** | `*.json` | 声明式定义模块的配置参数、元数据 |
| **逻辑文件** | `index.js` | 实现模块的业务逻辑和功能 |

### 设计优势

**1. 声明式配置**
- JSON 文件用于声明式定义模块的元数据和配置项
- 无需编写代码即可完成模块注册和参数配置
- 便于通过可视化工具进行管理和配置

**2. 逻辑与配置解耦**
- 配置变化无需修改代码，降低维护成本
- 相同的业务逻辑可以通过不同配置复用
- 配置文件可以独立版本管理和部署

**3. 自动化能力**
- 框架可自动扫描 JSON 配置完成模块注册
- 自动生成文档和配置表单
- 自动进行参数验证，减少重复代码

**4. 热更新支持**
- 配置文件可热更新，无需重启服务
- 支持动态添加/修改模块配置

**5. 团队协作优化**
- 配置人员和开发人员可并行工作
- 非开发人员也能参与模块配置
- 统一的配置格式降低沟通成本

### 模块类型

**core 核心模块**：框架基础模块，包括应用(app)、控制器(controller)、模型(model)、逻辑(logic)、插件(plugin)、服务(service)、视图(view)、中间件(middleware)等。

**com 公共组件**：可复用的公共组件，包括数据库(sql)、缓存(cache)、API管理(api)、事件(event)、任务(task)、静态资源(static)、模板(template)、MQTT、Socket等。

## 快速开始

### 安装

```bash
npm install mm_os
```

### 基本用法

```javascript
const { MM_os } = require('mm_os');

// 设置运行路径
$.run_path = __dirname;

// 创建服务器实例
const server = new MM_os({
  web: {
    host: '0.0.0.0',
    port: 8000,
    socket: true
  },
  mysql: {
    host: '127.0.0.1',
    port: 3306,
    user: 'root',
    password: '123456',
    database: 'test'
  },
  cache: {
    way: 'memory'
  }
});

// 启动服务器
async function startServer() {
  await server.init();
  await server.start();
  console.log('服务器启动成功');
}

startServer();
```

## 项目目录结构

基于 MM_OS 框架开发的项目采用标准化目录结构：

```
├── app/                    # 应用目录，包含多个独立应用
│   ├── app_name/           # 应用名称
│   │   ├── event_api/      # 事件API目录
│   │   │   ├── web/        # Web路由处理
│   │   │   │   ├── event.json    # 事件配置
│   │   │   │   └── main.js       # 入口文件
│   │   │   ├── api/        # API接口路由
│   │   │   ├── client/     # 客户端接口路由
│   │   │   └── manage/     # 管理后台路由
│   │   ├── plugin/         # 插件目录
│   │   │   ├── main/       # 主插件（业务逻辑）
│   │   │   │   └── api_{app}_{channel}/{api_name}/
│   │   │   │       ├── api.json   # API配置
│   │   │   │       ├── param.json # 参数验证配置
│   │   │   │       └── index.js   # API实现
│   │   │   └── server/     # 服务端插件（数据管理）
│   │   ├── pendant/        # 挂件组件目录
│   │   ├── static/         # 静态资源目录
│   │   ├── app.json        # 应用配置
│   │   └── index.js        # 应用入口
├── cache/                  # 缓存配置目录
├── com/                    # 公共组件目录
├── config/                 # 全局配置目录
│   ├── local.json          # 本地配置
│   ├── development.json    # 开发环境配置
│   └── production.json     # 生产环境配置
├── db/                     # 数据库文件目录（SQLite等）
├── static/                 # 全局静态资源
├── index.js                # 项目入口
└── config.json             # 主配置文件
```

## 应用开发

### 创建应用

每个应用包含独立的业务逻辑，应用配置文件 `app.json`：

```json
{
  "name": "user",
  "version": "1.0",
  "title": "用户",
  "description": "用于用户身份验证",
  "author": "developer",
  "scope": "server",
  "main": "./index.js",
  "func_name": "main",
  "sort": 10,
  "state": 1,
  "sql": {
    "way": "mysql",
    "mysql": {
      "host": "127.0.0.1",
      "port": 3306,
      "user": "root",
      "password": "password",
      "database": "example"
    }
  },
  "cache": {
    "way": "redis"
  }
}
```

### 事件路由配置 (event.json)

定义应用的路由规则：

```json
{
  "/api/user/list": {
    "method": "GET",
    "title": "获取用户列表",
    "auth": false
  },
  "/api/user/create": {
    "method": "POST",
    "title": "创建用户",
    "auth": true
  },
  "/user/*": {
    "method": "ALL",
    "title": "用户页面路由",
    "auth": false
  }
}
```

### 创建 API 接口

API 是 MM_OS 框架的核心组件，每个 API 包含三个文件：

#### 1. api.json - API 配置

```json
{
  "name": "user_sign_in",
  "title": "账户登录",
  "description": "用户登录接口，支持账号密码、手机号验证码、社交账号登录",
  "path": "/api/user/sign_in",
  "type": "api",
  "method": "ALL",
  "cache": 0,
  "param_path": "./param.json",
  "check_param": true,
  "sort": 1
}
```

**api.json 字段说明：**

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| name | string | 是 | API 唯一标识 |
| title | string | 是 | API 显示名称 |
| description | string | 否 | API 描述说明 |
| path | string | 是 | 访问路径 |
| type | string | 是 | 类型，固定为 "api" |
| method | string | 是 | 请求方法：GET、POST、ALL |
| cache | number | 否 | 缓存时间（秒），0 表示不缓存 |
| param_path | string | 否 | 参数验证配置文件路径 |
| check_param | boolean | 否 | 是否校验参数 |
| sort | number | 否 | 排序序号 |

#### 2. param.json - 参数验证配置

```json
{
  "title": "用户登录验证模型",
  "name": "user_sign_in",
  "filter": true,
  "get": {
    "query": ["account", "password", "code"],
    "query_required": ["account"]
  },
  "post": {
    "body": ["account", "password", "code", "phone"],
    "body_required": ["account"]
  },
  "list": [
    {
      "name": "account",
      "title": "账号",
      "type": "string",
      "string": {
        "min": 5,
        "max": 16,
        "format": "username"
      }
    },
    {
      "name": "password",
      "title": "密码",
      "type": "string",
      "string": {
        "min": 32,
        "max": 32,
        "format": "password"
      }
    },
    {
      "name": "phone",
      "title": "手机号码",
      "type": "string",
      "string": {
        "format": "phone",
        "range": [11, 11]
      }
    },
    {
      "name": "code",
      "title": "短信验证码",
      "type": "string"
    }
  ]
}
```

**param.json 字段说明：**

| 字段 | 类型 | 说明 |
|------|------|------|
| title | string | 验证模型名称 |
| name | string | 模型标识 |
| filter | boolean | 是否启用过滤 |
| get.query | array | GET 请求接受的查询参数 |
| get.query_required | array | GET 请求必填参数 |
| post.body | array | POST 请求接受的 body 参数 |
| post.body_required | array | POST 请求必填参数 |
| list | array | 参数验证规则列表 |

**参数类型支持：**
- `string`：字符串类型，支持 format（phone、email、username、password）、min、max、range
- `number`：数字类型，支持 min、max、range
- `boolean`：布尔类型
- `array`：数组类型
- `object`：对象类型

#### 3. index.js - API 实现

```javascript
/**
 * 账户登录接口
 * @param {Object} ctx HTTP上下文
 * @param {Object} db 数据管理器
 * @return {Object} 执行结果
 */
async function main(ctx, db) {
  // 获取请求参数
  var params = ctx.method === "POST" ? ctx.request.body : ctx.request.query;
  
  // 验证参数
  var account = params['account'];
  var password = params['password'];
  
  if (!account) {
    return { code: 30001, message: '账号不能为空' };
  }
  if (!password) {
    return { code: 30002, message: '密码不能为空' };
  }
  
  // 查询用户
  db.table = "user_account";
  db.key = "user_id";
  var users = await db.get({ username: account });
  
  if (users.length === 0) {
    return { code: 60001, message: '用户不存在' };
  }
  
  var user = users[0];
  
  // 验证密码
  var pass = (password + user.salt).md5();
  if (pass !== user.password) {
    return { code: 30003, message: '密码错误' };
  }
  
  // 设置登录状态
  ctx.session.user = user;
  
  // 返回结果
  return { 
    code: 200, 
    message: '登录成功',
    data: {
      user_id: user.user_id,
      username: user.username,
      nickname: user.nickname
    }
  };
}

exports.main = main;
```

### 事件处理入口 (main.js)

```javascript
// 使用API管理器
var api = $.admin.api('user_web', '网站-用户管理');
api.call('update');

/**
 * @description 接口主函数
 * @param {Object} ctx HTTP上下文
 * @param {Object} db 数据管理器
 * @return {Object} 执行结果
 */
async function main(ctx, db) {
  // 设置数据库连接
  $.push(db, $.admin.sql('sys').db(), true);
  
  // 使用模板引擎
  db.tpl = new $.Tpl();
  var bag = db.tpl.viewBag;
  bag.path = ctx.path;
  bag.query = ctx.query;
  
  // 执行API路由
  return await api.run(ctx, db);
}

exports.main = main;
```

## 配置说明

MM_OS 支持多种配置选项，包括：

- **web**：Web 服务器配置
- **mysql**：MySQL 数据库配置
- **sqlite**：SQLite 数据库配置
- **cache**：缓存配置（`way` 字段指定缓存方式：`memory`、`redis`、`mongodb`）
- **redis**：Redis 缓存配置
- **mongodb**：MongoDB 配置
- **mqtt**：MQTT 服务器配置
- **socket**：Socket 服务器配置

### 配置文件示例

```json
{
  "name": "mos",
  "title": "服务端系统",
  "log": {
    "level": "debug",
    "file": true
  },
  "web": {
    "state": true,
    "host": "0.0.0.0",
    "port": 8000,
    "socket": false,
    "cos": {
      "status": true,
      "origin": "*"
    },
    "static": {
      "state": 1,
      "root": "./static"
    }
  },
  "mysql": {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "password": "password",
    "database": "example"
  },
  "cache": {
    "way": "redis"
  },
  "redis": {
    "host": "localhost",
    "port": 6379,
    "password": "",
    "database": 0
  }
}
```

## 全局对象

MM_OS 提供了丰富的全局对象供开发使用：

### `$` 对象

| 属性 | 说明 |
|------|------|
| `$.sql` | 数据库操作对象 |
| `$.cache` | 缓存操作对象 |
| `$.log` | 日志对象 |
| `$.admin` | 管理员对象 |
| `$.eventer` | 事件总线 |
| `$.config` | 配置管理器 |
| `$.Tpl` | 模板引擎类 |
| `$.ret` | 返回结果工具 |
| `$.run_path` | 当前运行路径 |

### `$.ret` 返回工具

```javascript
// 成功返回
return $.ret.body(data);  // { code: 200, message: 'success', data: data }

// 错误返回
return $.ret.error(code, message);  // { code: code, message: message }
```

## 开发指南

1. **安装依赖**：`npm install`
2. **开发调试**：`npm run dev`
3. **运行测试**：`npm run test`

## 许可证

ISC
