本文件为 Claude Code (claude.ai/code) 在此代码库中工作时提供指导。
WIDESEAWCS_S7Simulator 是一个 S7 PLC 模拟器系统,用于模拟西门子 S7 系列 PLC 的服务器行为。采用前后端分离架构,支持同时运行多个 PLC 实例,并提供 Web 界面进行管理。
后端
- .NET 6.0 / ASP.NET Core Web API
- HslCommunication 12.6.3(S7 通信库)
- Swagger/OpenAPI
前端
- Vue 3.5 + TypeScript 5.7
- Vite 6.0(开发服务器 + 构建)
- Element Plus 2.9(UI 组件库)
- Pinia(状态管理)
- Vue Router 4.5
- Axios(HTTP 客户端)
# 运行后端服务器(默认端口 5137)
cd WIDESEAWCS_S7Simulator.Server
dotnet run
# 构建解决方案
dotnet build WIDESEAWCS_S7Simulator.slnx
# 运行单元测试
dotnet test WIDESEAWCS_S7Simulator.UnitTests
# 发布 Release 版本
dotnet publish -c Release
# 进入前端目录
cd WIDESEAWCS_S7Simulator.Web
# 安装依赖(使用 pnpm)
pnpm install
# 启动开发服务器(默认端口 3000,代理 /api 到后端 5137)
pnpm dev
# 构建生产版本
pnpm build
# 预览生产构建
pnpm preview
在两个终端中分别运行:
- 终端 1:cd WIDESEAWCS_S7Simulator.Server && dotnet run
- 终端 2:cd WIDESEAWCS_S7Simulator.Web && pnpm dev
访问 http://localhost:3000 使用 Web 界面。
┌─────────────────────────────────────────────────────────────┐
│ Vue 3 前端 │
│ (WIDESEAWCS_S7Simulator.Web - 端口 3000) │
│ - 实例列表、创建、编辑页面 │
│ - Axios API 客户端(代理到 /api) │
└─────────────────────────────────────────────────────────────┘
↓
↓ HTTP/REST API
↓
┌─────────────────────────────────────────────────────────────┐
│ ASP.NET Core API │
│ (WIDESEAWCS_S7Simulator.Server - 端口 5137) │
│ - SimulatorInstancesController (实例 CRUD) │
│ - MemoryController (内存读写) │
│ - ClientsController (客户端连接) │
└─────────────────────────────────────────────────────────────┘
↓
↓ 依赖注入
↓
┌─────────────────────────────────────────────────────────────┐
│ Core 业务逻辑层 │
│ (WIDESEAWCS_S7Simulator.Core) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ SimulatorInstanceManager - 实例生命周期管理 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ S7ServerInstance - 单个 S7 服务器实例 │ │
│ │ - HslCommunication.SiemensS7Server │ │
│ │ - MemoryStore (内存区域管理) │ │
│ │ - 客户端连接监控 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ MemoryStore - 内存区域抽象 │ │
│ │ - MRegion / DBRegion / IRegion / QRegion │ │
│ │ - TRegion / CRegion │ │
│ └─────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ FilePersistenceService - 配置持久化到 Data 目录 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
WIDESEAWCS_S7Simulator.Core - 核心业务逻辑
- Entities/: 实体类(InstanceConfig, InstanceState, S7ClientConnection)
- Enums/: 枚举(SiemensPLCType, InstanceStatus)
- Interfaces/: 核心接口(IS7ServerInstance, ISimulatorInstanceManager, IMemoryStore)
- Manager/: SimulatorInstanceManager(管理多个实例)
- Server/: S7ServerInstance(单个 S7 服务器实现)
- Memory/: 内存区域实现(MRegion, DBRegion, IRegion, QRegion, TRegion, CRegion, MemoryStore)
- Persistence/: FilePersistenceService(配置持久化)
WIDESEAWCS_S7Simulator.Server - ASP.NET Core Web API
- Controllers/: API 控制器
- Program.cs: 应用入口,配置 CORS、依赖注入、Swagger
WIDESEAWCS_S7Simulator.Application - 应用层(目前为空)
WIDESEAWCS_S7Simulator.Web - Vue 3 前端
- src/api/index.ts: Axios API 客户端
- src/types/index.ts: TypeScript 类型定义
- src/views/: 页面组件(HomeView, CreateView, EditView, DetailsView)
- src/router/: Vue Router 配置
- vite.config.ts: Vite 配置(开发服务器代理到后端)
WIDESEAWCS_S7Simulator.UnitTests - 单元测试
- Memory/: 内存区域测试
实例配置保存在 WIDESEAWCS_S7Simulator.Server/Data/ 目录下,每个实例一个 JSON 文件。
启动时会自动加载已保存的实例(默认不自动启动,需通过 API 或 UI 手动启动)。
所有 API 以 /api/ 为前缀,主要控制器:
- /api/SimulatorInstances/* - 实例管理(CRUD、启动/停止/重启)
- /api/Memory/* - 内存读写
- /api/Clients/* - 客户端连接信息
完整 API 文档:启动后端后访问 http://localhost:5137/swagger
S7 PLC 内存区域由 MemoryStore 统一管理:
- M 区:位存储器(默认 1024 字节)
- DB 区:数据块(可配置块数量和大小)
- I 区:输入区(默认 128 字节)
- Q 区:输出区(默认 128 字节)
- T 区:定时器(默认 100 个)
- C 区:计数器(默认 100 个)
地址格式支持:M100, DB1.DBD0, I0.0, Q0.0, T1, C1
后端使用 camelCase JSON 命名策略(System.Text.Json),枚举会序列化为字符串。
开发环境允许以下源访问 API:http://localhost:3000, http://localhost:5173, http://localhost:5174, http://localhost:3001
S7ServerInstance 支持通过 InstanceConfig.ActivationKey 设置 HSL Communication 库的激活码。
S7ServerInstance 每 5 秒通过检查 TCP 连接来监控客户端连接状态(使用 IPGlobalProperties.GetActiveTcpConnections())。
创建实例时需确保端口未被占用,多个实例不能使用相同端口。