<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>软角落-SoftNook</title><link>https://zelig.cn/</link><description>Good Luck To You!</description><item><title>AxonHub：构建企业级异步事件驱动架构的 Go 语言利器</title><link>https://zelig.cn/golang/1126.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142738cmhhfibxni.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h3 id=&quot;1-项目概述&quot;&gt;1. 项目概述&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AxonHub&lt;/strong&gt; 是一个基于 Go 语言开发的轻量级、高性能事件驱动架构（Event-Driven Architecture, EDA）框架。它的核心设计理念是为开发者提供一套标准化的机制，用于处理应用程序中的异步消息传递、事件分发以及解耦复杂的业务逻辑。&lt;/p&gt;

&lt;p&gt;在现代微服务架构中，同步的 REST 或 gRPC 调用往往会导致服务间的强耦合，一旦某个下游服务响应缓慢，会引发连锁反应（雪崩效应）。AxonHub 通过引入“事件总线（Event Bus）”的概念，允许生产者仅发送事件而无需关心谁在消费，从而实现真正的异步解耦。&lt;/p&gt;

&lt;h3 id=&quot;2-核心设计理念&quot;&gt;2. 核心设计理念&lt;/h3&gt;

&lt;p&gt;AxonHub 的设计参考了领域驱动设计（DDD）中的事件驱动模式，其核心组件包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Event (事件)&lt;/strong&gt;：代表系统中已经发生的事实（例如 &lt;code&gt;OrderCreated&lt;/code&gt;, &lt;code&gt;UserRegistered&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Publisher (发布者)&lt;/strong&gt;：将事件推送到 Hub 的组件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Subscriber/Handler (订阅者/处理器)&lt;/strong&gt;：监听特定事件并在事件触发时执行相应的业务逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hub (中心枢纽)&lt;/strong&gt;：负责事件的路由、分发和生命周期管理。&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-关键特性&quot;&gt;3. 关键特性&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;类型安全&lt;/strong&gt;：利用 Go 的类型系统，确保事件在传递过程中保持结构完整。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步非阻塞&lt;/strong&gt;：通过内部通道（Channel）和协程（Goroutine）机制，确保发布事件不会阻塞主业务流程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活的订阅机制&lt;/strong&gt;：支持针对特定事件类型的精准订阅。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;轻量级依赖&lt;/strong&gt;：无需依赖复杂的外部中间件（如 Kafka 或 RabbitMQ）即可在单体应用或轻量级服务中快速搭建事件流。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h3 id=&quot;4-快速上手实例&quot;&gt;4. 快速上手实例&lt;/h3&gt;

&lt;p&gt;为了让你直观理解 AxonHub 的工作方式，我们模拟一个典型的“电商下单”场景：当用户下单成功后，系统需要同步触发：&lt;strong&gt;发送通知邮件&lt;/strong&gt; 和 &lt;strong&gt;扣减库存&lt;/strong&gt;。&lt;/p&gt;

&lt;h4 id=&quot;4-1-定义事件结构&quot;&gt;4.1 定义事件结构&lt;/h4&gt;

&lt;p&gt;首先，定义一个代表“订单创建”的事件。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;package main

import &amp;#34;fmt&amp;#34;

// OrderCreatedEvent 定义订单创建事件
type OrderCreatedEvent struct {
    OrderID   string
    UserID    string
    Amount    float64
}
&lt;/pre&gt;
&lt;h4 id=&quot;4-2-实现事件处理器-handlers&quot;&gt;4.2 实现事件处理器 (Handlers)&lt;/h4&gt;

&lt;p&gt;创建两个不同的处理器，分别处理邮件发送和库存扣减。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;// EmailHandler 处理发送邮件逻辑
type EmailHandler struct{}

func (h *EmailHandler) Handle(event interface{}) {
    if e, ok := event.(*OrderCreatedEvent); ok {
        fmt.Printf(&amp;#34;[邮件服务] 正在向用户 %s 发送订单 %s 的确认邮件...\n&amp;#34;, e.UserID, e.OrderID)
    }
}

// InventoryHandler 处理库存扣减逻辑
type InventoryHandler struct{}

func (h *InventoryHandler) Handle(event interface{}) {
    if e, ok := event.(*OrderCreatedEvent); ok {
        fmt.Printf(&amp;#34;[库存服务] 订单 %s 触发，正在扣减商品库存...\n&amp;#34;, e.OrderID)
    }
}
&lt;/pre&gt;
&lt;h4 id=&quot;4-3-组装与运行&quot;&gt;4.3 组装与运行&lt;/h4&gt;

&lt;p&gt;将处理器注册到 AxonHub，并发布事件。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;package main

import (
    &amp;#34;github.com/looplj/axonhub&amp;#34; // 假设导入路径
)

func main() {
    // 1. 初始化 AxonHub
    hub := axonhub.NewHub()

    // 2. 实例化处理器
    emailSvc := &amp;amp;EmailHandler{}
    inventorySvc := &amp;amp;InventoryHandler{}

    // 3. 订阅事件
    // 将 OrderCreatedEvent 类型与对应的处理器绑定
    hub.Subscribe(OrderCreatedEvent{}, emailSvc)
    hub.Subscribe(OrderCreatedEvent{}, inventorySvc)

    // 4. 模拟业务触发：用户下单
    orderEvent := &amp;amp;OrderCreatedEvent{
        OrderID: &amp;#34;ORD_20231027_001&amp;#34;,
        UserID:  &amp;#34;USER_888&amp;#34;,
        Amount:   299.00,
    }

    fmt.Println(&amp;#34;&amp;gt;&amp;gt;&amp;gt; 业务层：订单已创建，发布事件...&amp;#34;)
    hub.Publish(orderEvent)

    // 为了演示，防止主进程直接退出
    select {} 
}
&lt;/pre&gt;
&lt;hr&gt;

&lt;h3 id=&quot;5-深度分析-为什么选择-axonhub&quot;&gt;5. 深度分析：为什么选择 AxonHub？&lt;/h3&gt;

&lt;h4 id=&quot;场景-a-消除-面条代码&quot;&gt;场景 A：消除“面条代码”&lt;/h4&gt;

&lt;p&gt;在没有事件总线的情况下，你的下单代码可能是这样的：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;func CreateOrder() {
    db.SaveOrder()
    emailSvc.SendEmail()      // 强耦合
    inventorySvc.ReduceStock() // 强耦合
    logSvc.LogAction()         // 强耦合
}
&lt;/pre&gt;
&lt;p&gt;如果以后增加一个“发放积分”的需求，你必须修改 &lt;code&gt;CreateOrder&lt;/code&gt; 函数。而使用 AxonHub 后，&lt;code&gt;CreateOrder&lt;/code&gt; 只需要 &lt;code&gt;hub.Publish(OrderCreatedEvent{})&lt;/code&gt;，新增功能只需增加一个新的 &lt;code&gt;Subscriber&lt;/code&gt;，无需触动核心下单逻辑。&lt;/p&gt;

&lt;h4 id=&quot;场景-b-性能优化&quot;&gt;场景 B：性能优化&lt;/h4&gt;

&lt;p&gt;通过将非核心路径（如发送邮件、统计分析）移至异步处理器中，主请求的响应时间（Latency）将大幅降低，极大地提升了用户体验。&lt;/p&gt;

&lt;h3 id=&quot;6-进阶建议与扩展方向&quot;&gt;6. 进阶建议与扩展方向&lt;/h3&gt;

&lt;p&gt;如果你在生产环境中使用 AxonHub，可以考虑以下扩展方向：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;持久化队列&lt;/strong&gt;：目前的 AxonHub 主要在内存中运行。对于关键业务，可以为其实现一个基于 Redis 或 MongoDB 的持久化层，防止程序崩溃导致事件丢失。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误重试机制&lt;/strong&gt;：在 &lt;code&gt;Handler&lt;/code&gt; 中引入重试逻辑（Retry Policy），当第三方 API（如邮件服务）暂时不可用时，能够自动重新触发。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分布式扩展&lt;/strong&gt;：将 AxonHub 作为本地代理，底层对接 NATS 或 Kafka，从而将单机事件总线升级为分布式事件总线。&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;7-总结&quot;&gt;7. 总结&lt;/h3&gt;

&lt;p&gt;AxonHub 为 Go 开发者提供了一种优雅的方式来处理系统内部的通信。它通过简单的 &lt;code&gt;Publish/Subscribe&lt;/code&gt; 模式，将复杂的业务依赖关系转化为清晰的事件流。无论是在构建中型单体应用，还是在微服务之间寻找轻量级的解耦方案，AxonHub 都是一个极具潜力的选择。&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 14:24:15 +0800</pubDate></item><item><title>go-深入解析 docker-agent：构建轻量化、可扩展的 Docker 容器管理代理</title><link>https://zelig.cn/golang/1125.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142725hcrjlbdtmx.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h3 id=&quot;什么是-docker-agent&quot;&gt;什么是 docker-agent？&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docker-agent&lt;/code&gt; 是由 Docker 官方维护的一个基于 Go 语言开发的轻量级代理项目。它的核心设计目标是为容器化环境提供一个标准化的、可扩展的代理层，用于在宿主机或容器内部执行特定的管理任务、监控指标采集或状态上报。&lt;/p&gt;

&lt;p&gt;在复杂的微服务架构中，我们经常需要一个能够与 Docker Daemon 交互，同时又能将特定数据（如健康检查结果、资源指标、自定义元数据）发送到远程控制平面（Control Plane）的中间件。&lt;code&gt;docker-agent&lt;/code&gt; 正是为了填补这一空白而设计的。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;核心设计理念&quot;&gt;核心设计理念&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docker-agent&lt;/code&gt; 采用了典型的 &lt;strong&gt;Sidecar（边车）&lt;/strong&gt; 或 &lt;strong&gt;DaemonSet&lt;/strong&gt; 部署模式。其核心逻辑围绕以下三个维度展开：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;轻量化（Lightweight）&lt;/strong&gt;：使用 Go 语言编写，确保极低的内存占用和快速的启动速度，避免代理程序本身成为系统的资源瓶颈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解耦（Decoupling）&lt;/strong&gt;：将具体的业务逻辑（如如何上报数据）与 Docker API 的交互逻辑分离。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可扩展性（Extensibility）&lt;/strong&gt;：通过接口定义，允许开发者轻松地为 agent 添加新的功能模块，而无需重构核心调度逻辑。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h3 id=&quot;关键功能特性&quot;&gt;关键功能特性&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docker API 集成&lt;/strong&gt;：能够无缝调用 Docker Engine API，获取容器状态、镜像信息、网络配置等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态监控与上报&lt;/strong&gt;：支持定时轮询容器状态，并将结果推送到指定的后端接口。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;生命周期管理&lt;/strong&gt;：能够感知容器的启动、停止和崩溃，触发相应的响应机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置驱动&lt;/strong&gt;：支持通过环境变量或配置文件动态调整运行行为。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h3 id=&quot;快速上手实例&quot;&gt;快速上手实例&lt;/h3&gt;

&lt;p&gt;为了让你直观理解 &lt;code&gt;docker-agent&lt;/code&gt; 的工作方式，我们通过一个模拟场景：&lt;strong&gt;构建一个自动监控容器 CPU 占用并上报的代理。&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;1-环境准备&quot;&gt;1. 环境准备&lt;/h4&gt;

&lt;p&gt;确保你的机器上已安装：
*   Go 1.20+
*   Docker Engine
*   Git&lt;/p&gt;

&lt;h4 id=&quot;2-克隆与编译&quot;&gt;2. 克隆与编译&lt;/h4&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;git clone https://github.com/docker/docker-agent.git
cd docker-agent
go build -o docker-agent .
&lt;/pre&gt;
&lt;h4 id=&quot;3-运行代理&quot;&gt;3. 运行代理&lt;/h4&gt;

&lt;p&gt;为了让 &lt;code&gt;docker-agent&lt;/code&gt; 能够访问宿主机的 Docker 守护进程，通常需要挂载 &lt;code&gt;/var/run/docker.sock&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;使用 Docker 运行该代理：&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;docker run -d \
  --name my-docker-agent \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e AGENT_INTERVAL=10s \
  -e REPORT_ENDPOINT=&amp;#34;http://api.monitor.local/report&amp;#34; \
  docker-agent:latest
&lt;/pre&gt;
&lt;h4 id=&quot;4-逻辑实现示例-伪代码&quot;&gt;4. 逻辑实现示例（伪代码）&lt;/h4&gt;

&lt;p&gt;如果你想在 &lt;code&gt;docker-agent&lt;/code&gt; 的基础上扩展一个自定义的“容器健康检查”逻辑，你可以参考以下 Go 代码结构：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;package main

import (
    &amp;#34;context&amp;#34;
    &amp;#34;fmt&amp;#34;
    &amp;#34;github.com/docker/docker-agent/pkg/docker&amp;#34; // 假设的包路径
)

func main() {
    // 1. 初始化 Docker 客户端
    client, err := docker.NewClient()
    if err != nil {
        panic(err)
    }

    // 2. 定义一个简单的监控循环
    for {
        containers, _ := client.ListContainers(context.Background())
        for _, container := range containers {
            fmt.Printf(&amp;#34;检查容器: %s, 状态: %s\n&amp;#34;, container.Names[0], container.State)
            
            // 3. 模拟上报逻辑
            reportStatus(container.ID, container.State)
        }
        time.Sleep(10 * time.Second)
    }
}

func reportStatus(id string, state string) {
    // 调用远程 API 上报数据
    fmt.Printf(&amp;#34;Reporting %s is %s to remote server...\n&amp;#34;, id, state)
}
&lt;/pre&gt;
&lt;hr&gt;

&lt;h3 id=&quot;应用场景分析&quot;&gt;应用场景分析&lt;/h3&gt;

&lt;h4 id=&quot;场景-a-自定义监控指标采集&quot;&gt;场景 A：自定义监控指标采集&lt;/h4&gt;

&lt;p&gt;标准的 Prometheus 采集可能过于沉重。通过 &lt;code&gt;docker-agent&lt;/code&gt;，你可以编写极简的逻辑，仅采集你关心的 3 个关键指标，并以极低频率推送到时序数据库。&lt;/p&gt;

&lt;h4 id=&quot;场景-b-自动化运维触发器&quot;&gt;场景 B：自动化运维触发器&lt;/h4&gt;

&lt;p&gt;当 &lt;code&gt;docker-agent&lt;/code&gt; 检测到某个关键容器进入 &lt;code&gt;Exited&lt;/code&gt; 状态时，它可以立即触发一个 Webhook，通知运维团队或启动自动重启脚本，而无需等待外部监控系统的轮询周期。&lt;/p&gt;

&lt;h4 id=&quot;场景-c-容器元数据同步&quot;&gt;场景 C：容器元数据同步&lt;/h4&gt;

&lt;p&gt;在多集群环境下，需要将容器的标签（Labels）与外部资产管理系统同步。&lt;code&gt;docker-agent&lt;/code&gt; 可以扫描所有容器标签并实时同步到 CMDB。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;总结与建议&quot;&gt;总结与建议&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;docker-agent&lt;/code&gt; 并不是一个功能完备的“产品”，而是一个&lt;strong&gt;工业级的脚手架（Scaffold）&lt;/strong&gt;。它为你处理好了最麻烦的 Docker API 连接、并发控制和基础运行环境。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;如果你面临以下需求，建议使用该项目：&lt;/strong&gt;
*   需要开发一个轻量级的 Docker 插件。
*   需要构建一个私有的容器状态监控代理。
*   希望学习 Docker 官方如何组织 Go 语言的代理类项目结构。&lt;/p&gt;

&lt;p&gt;通过将业务逻辑注入到这个轻量级的代理中，你可以快速构建出高性能、低损耗的容器管理工具。&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 14:19:15 +0800</pubDate></item><item><title>用 Go 语言重塑高性能网络通信：深度解析 Shannon 框架的架构之美与实战指南</title><link>https://zelig.cn/golang/1124.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142714sbxqoxzqif.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;探索-shannon-构建高性能-go-网络服务的利器&quot;&gt;探索 Shannon：构建高性能 Go 网络服务的利器&lt;/h1&gt;

&lt;p&gt;在现代分布式系统和微服务架构中，网络通信的效率直接决定了系统的吞吐量与响应延迟。虽然 Go 语言原生的 &lt;code&gt;net&lt;/code&gt; 包已经提供了极其强大的并发能力，但在面对极高并发、复杂协议解析以及精细化内存管理的需求时，开发者往往需要更底层的控制力。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shannon&lt;/strong&gt; (GitHub: &lt;code&gt;Kocoro-lab/Shannon&lt;/code&gt;) 正是为了填补这一空白而生的一个高性能网络通信框架。它旨在为 Go 开发者提供一套简洁且高效的 API，在保持 Go 语言开发效率的同时，尽可能地压榨网络 I/O 的性能。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;1-为什么选择-shannon&quot;&gt;1. 为什么选择 Shannon？&lt;/h2&gt;

&lt;p&gt;在传统的 Go 网络编程中，我们通常为每个连接启动一个 goroutine (&lt;code&gt;go handleConn(conn)&lt;/code&gt;)。虽然这种模型在大多数场景下表现优异，但在处理数万个长连接且流量波动剧烈的场景时，会面临以下挑战：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内存开销&lt;/strong&gt;：每个 goroutine 虽小，但海量连接仍会占用大量内存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GC 压力&lt;/strong&gt;：频繁地创建和销毁缓冲区（Buffer）会导致垃圾回收压力剧增。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调度开销&lt;/strong&gt;：极高频的上下文切换在极端性能场景下会成为瓶颈。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Shannon 的核心设计目标&lt;/strong&gt;是通过优化缓冲区管理、精简协议栈处理流程以及提供灵活的事件驱动机制，降低资源消耗并提升数据传输效率。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;2-核心架构特性&quot;&gt;2. 核心架构特性&lt;/h2&gt;

&lt;h3 id=&quot;2-1-零拷贝与缓冲区池化&quot;&gt;2.1 零拷贝与缓冲区池化&lt;/h3&gt;

&lt;p&gt;Shannon 内部实现了高效的 Buffer 池化机制。它避免了在每次读取数据时重新分配内存，而是通过复用内存块来降低 GC 的频率。这种设计在处理高频小包传输时具有显著的性能优势。&lt;/p&gt;

&lt;h3 id=&quot;2-2-灵活的协议编解码&quot;&gt;2.2 灵活的协议编解码&lt;/h3&gt;

&lt;p&gt;Shannon 将传输层与协议层解耦。开发者可以通过实现简单的接口，快速定义自己的私有协议（如：长度字段 + 数据体），而无需关心底层的 Socket 读写细节。&lt;/p&gt;

&lt;h3 id=&quot;2-3-异步非阻塞模型&quot;&gt;2.3 异步非阻塞模型&lt;/h3&gt;

&lt;p&gt;虽然 Go 语言在底层将非阻塞 I/O 封装成了同步写法，但 Shannon 在框架层进一步优化了数据的流动方式，确保在处理复杂业务逻辑时，网络 I/O 不会被阻塞，从而最大化利用 CPU 核心。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;3-快速上手实例&quot;&gt;3. 快速上手实例&lt;/h2&gt;

&lt;p&gt;为了让大家直观感受 Shannon 的使用，下面我们将构建一个简单的 &lt;strong&gt;Echo 服务器&lt;/strong&gt;（即：服务器收到什么就原样返回什么）。&lt;/p&gt;

&lt;h3 id=&quot;3-1-环境准备&quot;&gt;3.1 环境准备&lt;/h3&gt;

&lt;p&gt;首先，克隆项目并安装依赖：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;go get github.com/Kocoro-lab/Shannon
&lt;/pre&gt;
&lt;h3 id=&quot;3-2-编写-echo-服务器&quot;&gt;3.2 编写 Echo 服务器&lt;/h3&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;package main

import (
	&amp;#34;fmt&amp;#34;
	&amp;#34;log&amp;#34;
	&amp;#34;github.com/Kocoro-lab/Shannon&amp;#34; 
)

func main() {
	// 1. 创建一个 Shannon 实例
	// 这里的配置可以根据实际硬件性能进行调整
	server := Shannon.NewServer(Shannon.Config{
		Port:    8080,
		ReadBuf: 1024, // 读取缓冲区大小
		WriteBuf: 1024, // 写入缓冲区大小
	})

	// 2. 定义连接处理逻辑
	// 当有新客户端连接时，会触发此回调
	server.OnConnect(func(conn Shannon.Conn) {
		fmt.Printf(&amp;#34;新客户端连接: %s\n&amp;#34;, conn.RemoteAddr())
	})

	// 3. 定义数据接收处理逻辑
	// 当接收到数据包时，会触发此回调
	server.OnMessage(func(conn Shannon.Conn, data []byte) {
		fmt.Printf(&amp;#34;收到消息: %s\n&amp;#34;, string(data))
		
		// 将接收到的数据原样发送回去 (Echo)
		_, err := conn.Write(data)
		if err != nil {
			log.Printf(&amp;#34;发送失败: %v&amp;#34;, err)
		}
	})

	// 4. 定义连接关闭逻辑
	server.OnClose(func(conn Shannon.Conn) {
		fmt.Printf(&amp;#34;客户端断开连接: %s\n&amp;#34;, conn.RemoteAddr())
	})

	// 5. 启动服务器
	fmt.Println(&amp;#34;Shannon Echo Server 正在运行在 :8080...&amp;#34;)
	if err := server.Start(); err != nil {
		log.Fatalf(&amp;#34;服务器启动失败: %v&amp;#34;, err)
	}
}
&lt;/pre&gt;
&lt;h3 id=&quot;3-3-测试运行&quot;&gt;3.3 测试运行&lt;/h3&gt;

&lt;p&gt;你可以使用 &lt;code&gt;telnet&lt;/code&gt; 或 &lt;code&gt;nc&lt;/code&gt; (netcat) 来测试这个服务器：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;nc localhost 8080
# 输入: Hello Shannon!
# 预期输出: Hello Shannon!
&lt;/pre&gt;
&lt;hr&gt;

&lt;h2 id=&quot;4-进阶应用场景-自定义协议解析&quot;&gt;4. 进阶应用场景：自定义协议解析&lt;/h2&gt;

&lt;p&gt;在实际生产中，我们很少使用纯文本，通常会使用 &lt;code&gt;[Header][Length][Body]&lt;/code&gt; 这种格式。Shannon 允许你通过自定义拦截器或处理函数来实现协议解析。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;示例：实现一个简单的长度前缀协议&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;server.OnMessage(func(conn Shannon.Conn, data []byte) {
    if len(data) &amp;lt; 4 {
        return // 数据不足以包含长度头
    }
    
    // 假设前4个字节是 BigEndian 的长度字段
    length := binary.BigEndian.Uint32(data[:4])
    payload := data[4:]
    
    if uint32(len(payload)) &amp;lt; length {
        // 处理粘包/半包逻辑...
        return
    }
    
    // 处理实际业务逻辑
    processBusiness(payload)
})
&lt;/pre&gt;
&lt;hr&gt;

&lt;h2 id=&quot;5-性能调优建议&quot;&gt;5. 性能调优建议&lt;/h2&gt;

&lt;p&gt;如果你打算在生产环境中使用 Shannon，建议关注以下几个调优方向：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;缓冲区对齐&lt;/strong&gt;：根据你的业务数据包大小，合理设置 &lt;code&gt;ReadBuf&lt;/code&gt; 和 &lt;code&gt;WriteBuf&lt;/code&gt;。如果包很大，设置过小会导致频繁的系统调用；如果包很小，设置过大则浪费内存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发控制&lt;/strong&gt;：虽然 Shannon 处理了 I/O，但如果 &lt;code&gt;OnMessage&lt;/code&gt; 内部涉及复杂的数据库查询或远程调用，建议将任务交给一个独立的 &lt;code&gt;Worker Pool&lt;/code&gt;（工作池），避免阻塞网络线程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep-Alive 策略&lt;/strong&gt;：在长连接场景下，务必配置心跳检测机制，及时清理死连接，防止文件描述符（FD）耗尽。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;6-总结&quot;&gt;6. 总结&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Kocoro-lab/Shannon&lt;/code&gt; 为 Go 开发者提供了一个在“极简开发”与“极致性能”之间取得平衡的方案。它通过对内存的精细管理和对 I/O 流程的优化，使得构建高性能的 TCP/UDP 服务变得更加轻松。&lt;/p&gt;

&lt;p&gt;无论你是想开发一个高性能的游戏后端、一个自定义的中间件，还是一个实时数据推送系统，Shannon 都能为你提供坚实的基础支撑。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;项目地址回顾&lt;/strong&gt;： &lt;a href=&quot;https://github.com/Kocoro-lab/Shannon&quot;&gt;https://github.com/Kocoro-lab/Shannon&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 13:52:15 +0800</pubDate></item><item><title>用 Go 语言重塑控制理论：Gonzo 框架深度解析与实战指南</title><link>https://zelig.cn/golang/1123.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142659svemrvhjgg.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;gonzo-为控制理论而生的-go-语言数值计算库&quot;&gt;Gonzo：为控制理论而生的 Go 语言数值计算库&lt;/h1&gt;

&lt;p&gt;在科学计算和控制理论领域，MATLAB 和 Python (SciPy/NumPy) 长期占据主导地位。然而，随着工业自动化、机器人控制以及大规模分布式系统的兴起，开发者对&lt;strong&gt;执行效率&lt;/strong&gt;、&lt;strong&gt;类型安全&lt;/strong&gt;以及&lt;strong&gt;部署便捷性&lt;/strong&gt;提出了更高要求。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gonzo&lt;/code&gt; 是一个旨在为 Go 语言提供强大数值计算和控制理论支持的开源项目。它不仅填补了 Go 在线性代数和信号处理方面的空白，更通过简洁的 API 实现了复杂控制算法的快速原型开发。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;核心特性&quot;&gt;核心特性&lt;/h2&gt;

&lt;h3 id=&quot;1-高效的线性代数运算&quot;&gt;1. 高效的线性代数运算&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;gonzo&lt;/code&gt; 提供了对矩阵（Matrix）和向量（Vector）的高级抽象。不同于简单的二维切片，它在底层优化了内存布局，支持常见的矩阵运算：
- 矩阵乘法、转置、求逆。
- 特征值分解与奇异值分解（SVD）。
- 快速的切片操作与索引映射。&lt;/p&gt;

&lt;h3 id=&quot;2-控制理论工具集&quot;&gt;2. 控制理论工具集&lt;/h3&gt;

&lt;p&gt;该项目不仅是数学库，更是控制理论的实现集。它内置了：
- &lt;strong&gt;传递函数 (Transfer Functions)&lt;/strong&gt;：定义 LTI（线性时不变）系统。
- &lt;strong&gt;状态空间模型 (State-Space Models)&lt;/strong&gt;：通过 &lt;span class=&quot;math inline&quot;&gt;\(\dot{x} = Ax + Bu\)&lt;/span&gt; 描述系统动态。
- &lt;strong&gt;离散化工具&lt;/strong&gt;：将连续时间系统转换为离散时间系统，便于在嵌入式设备上部署。&lt;/p&gt;

&lt;h3 id=&quot;3-强类型安全与并发支持&quot;&gt;3. 强类型安全与并发支持&lt;/h3&gt;

&lt;p&gt;利用 Go 的静态类型检查，&lt;code&gt;gonzo&lt;/code&gt; 在编译期就能拦截大部分维度不匹配的矩阵运算错误，避免了 Python 中常见的运行时 &lt;code&gt;ValueError&lt;/code&gt;。同时，其设计天然适配 Go 的并发模型，能够高效处理多通道信号处理。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;快速上手实例&quot;&gt;快速上手实例&lt;/h2&gt;

&lt;p&gt;为了展示 &lt;code&gt;gonzo&lt;/code&gt; 的实际应用，我们通过一个经典的&lt;strong&gt;二阶系统模拟&lt;/strong&gt;来演示如何定义系统并进行计算。&lt;/p&gt;

&lt;h3 id=&quot;场景-模拟一个简单的弹簧-阻尼系统&quot;&gt;场景：模拟一个简单的弹簧-阻尼系统&lt;/h3&gt;

&lt;p&gt;假设我们要描述一个质量-弹簧-阻尼系统，其状态向量为 &lt;span class=&quot;math inline&quot;&gt;\(x = [位置, 速度]^T\)&lt;/span&gt;。&lt;/p&gt;

&lt;h4 id=&quot;1-定义状态空间模型&quot;&gt;1. 定义状态空间模型&lt;/h4&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;package main

import (
	&amp;#34;fmt&amp;#34;
	&amp;#34;github.com/control-theory/gonzo&amp;#34;
)

func main() {
	// 定义系统矩阵 A (状态转移矩阵)
	// 假设 A = [[0, 1], [-k/m, -c/m]]
	A := gonzo.NewMatrix([][]float64{
		{0, 1},
		{-2.0, -0.5}, 
	})

	// 定义输入矩阵 B
	B := gonzo.NewMatrix([][]float64{
		{0},
		{1.0},
	})

	// 定义输出矩阵 C (我们只关心位置)
	C := gonzo.NewMatrix([][]float64{
		{1, 0},
	})

	// 定义直接传输矩阵 D
	D := gonzo.NewMatrix([][]float64{
		{0},
	})

	// 创建状态空间模型
	sys := gonzo.NewSS(A, B, C, D)

	fmt.Printf(&amp;#34;系统阶数: %d\n&amp;#34;, sys.Order())
}
&lt;/pre&gt;
&lt;h4 id=&quot;2-计算系统响应&quot;&gt;2. 计算系统响应&lt;/h4&gt;

&lt;p&gt;在控制理论中，我们经常需要计算系统的增益或稳定性。使用 &lt;code&gt;gonzo&lt;/code&gt; 可以快速获取系统的特征值：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;// 计算 A 矩阵的特征值以判断系统稳定性
eigenvalues := A.Eigenvalues()
fmt.Println(&amp;#34;系统特征值:&amp;#34;, eigenvalues)

// 如果所有特征值的实部均为负，则系统稳定
&lt;/pre&gt;
&lt;hr&gt;

&lt;h2 id=&quot;gonzo-vs-传统工具-matlab-python&quot;&gt;Gonzo vs 传统工具 (MATLAB/Python)&lt;/h2&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;维度&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;MATLAB / Python&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Gonzo (Go)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;部署&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;需要庞大的运行时环境 (Runtime)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;编译为单个静态二进制文件&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;性能&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;依赖 C 扩展，全局解释器锁 (GIL)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;原生编译，高效并发 (Goroutines)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型检查&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;动态类型，运行时报错&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静态强类型，编译期拦截&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;集成度&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;适合科研、离线分析&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;适合实时控制、云原生后端、边缘计算&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&quot;适用场景&quot;&gt;适用场景&lt;/h2&gt;

&lt;h3 id=&quot;1-工业机器人控制器&quot;&gt;1. 工业机器人控制器&lt;/h3&gt;

&lt;p&gt;在需要毫秒级响应的机器人关节控制中，Go 的低延迟特性结合 &lt;code&gt;gonzo&lt;/code&gt; 的矩阵运算，可以实现高效的 PID 调节或 LQR（线性二次调节器）控制。&lt;/p&gt;

&lt;h3 id=&quot;2-金融量化交易&quot;&gt;2. 金融量化交易&lt;/h3&gt;

&lt;p&gt;金融时间序列分析本质上是信号处理。&lt;code&gt;gonzo&lt;/code&gt; 提供的数值计算能力可用于构建卡尔曼滤波器（Kalman Filter）以实时跟踪资产价格趋势。&lt;/p&gt;

&lt;h3 id=&quot;3-模拟仿真后端&quot;&gt;3. 模拟仿真后端&lt;/h3&gt;

&lt;p&gt;如果你正在开发一个基于 Web 的物理仿真器，使用 Go 作为后端并引入 &lt;code&gt;gonzo&lt;/code&gt;，可以快速计算物理状态转移并实时通过 WebSocket 推送给前端。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;进阶建议-如何深度使用&quot;&gt;进阶建议：如何深度使用&lt;/h2&gt;

&lt;p&gt;如果你打算在生产环境中使用 &lt;code&gt;gonzo&lt;/code&gt;，建议关注以下几点：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;内存复用&lt;/strong&gt;：在高性能循环中，尽量避免在循环内创建新的 &lt;code&gt;Matrix&lt;/code&gt; 对象，尝试复用已有的切片以减少 GC 压力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结合 &lt;code&gt;gonum&lt;/code&gt;&lt;/strong&gt;：&lt;code&gt;gonzo&lt;/code&gt; 在设计上倾向于控制理论的易用性。对于极大规模的通用数值计算，可以考虑将其与 &lt;code&gt;gonum&lt;/code&gt;（Go 社区最强大的数值库）结合使用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;单元测试&lt;/strong&gt;：由于数值计算对精度敏感，建议为每一个控制律实现编写基于 &lt;span class=&quot;math inline&quot;&gt;\(\epsilon\)&lt;/span&gt; 容差的测试用例。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gonzo&lt;/code&gt; 不仅仅是一个数学库，它为 Go 语言开发者提供了一套进入控制理论世界的门票。它将复杂的数学公式转化为可维护的代码结构，让开发者能够摆脱对重量级科学计算软件的依赖，直接在生产环境中实现高性能的控制算法。&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 12:33:15 +0800</pubDate></item><item><title># 突破PLC编程限制：Pascal FB4D——在工业自动化中实现通用编程的艺术</title><link>https://zelig.cn/delphi/1122.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/07/20260711111604kxskajxtyr.svg&quot; alt=&quot;# 突破PLC编程限制：Pascal FB4D——在工业自动化中实现通用编程的艺术&quot;&gt;&lt;/p&gt;&lt;h2 id=&quot;什么是-pascal-fb4d&quot;&gt;什么是 Pascal FB4D？&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pascal FB4D&lt;/strong&gt; 是一个由 Schneider Infosystems 开发的开源项目，旨在将 Pascal 语言的编程能力引入到符合 IEC 61131-3 标准的 PLC（可编程逻辑控制器）环境中。&lt;/p&gt;

&lt;p&gt;在传统的工业自动化编程中，工程师通常依赖于梯形图 (LAD)、结构化文本 (ST) 或功能块图 (FBD)。虽然 ST 语言在逻辑处理上已经非常接近高级语言，但在处理复杂的数据结构、动态内存管理以及大规模算法实现时，仍然存在一定的局限性。&lt;/p&gt;

&lt;p&gt;FB4D 的核心理念是：&lt;strong&gt;通过一个高度优化的编译器/转换层，允许开发者使用类 Pascal 的语法编写复杂的逻辑，并将其转化为 PLC 能够执行的功能块 (Function Blocks)&lt;/strong&gt;。它不仅是一个库，更是一套将高级语言特性与工业实时控制结合的方案。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;核心技术特性&quot;&gt;核心技术特性&lt;/h2&gt;

&lt;h3 id=&quot;1-强类型安全与结构化&quot;&gt;1. 强类型安全与结构化&lt;/h3&gt;

&lt;p&gt;Pascal 语言以其严谨的类型检查著称。FB4D 将这种特性带入 PLC，有效减少了在运行时因类型不匹配而导致的系统崩溃（Runtime Error），这对于安全性要求极高的工业现场至关重要。&lt;/p&gt;

&lt;h3 id=&quot;2-模块化功能块封装&quot;&gt;2. 模块化功能块封装&lt;/h3&gt;

&lt;p&gt;FB4D 将复杂的算法封装在 &lt;code&gt;FB&lt;/code&gt; (Function Block) 之中。这意味着你可以编写一个复杂的 PID 算法或数据处理协议，然后像使用标准库一样，在 PLC 的主程序中多次实例化该块，实现代码的高度复用。&lt;/p&gt;

&lt;h3 id=&quot;3-优化内存占用&quot;&gt;3. 优化内存占用&lt;/h3&gt;

&lt;p&gt;PLC 的内存资源极其宝贵。FB4D 在转换过程中会对变量作用域和内存布局进行优化，确保在提供高级语言便利的同时，不会导致 PLC 内存溢出或扫描周期（Scan Cycle）大幅增加。&lt;/p&gt;

&lt;h3 id=&quot;4-跨平台兼容性&quot;&gt;4. 跨平台兼容性&lt;/h3&gt;

&lt;p&gt;该项目旨在支持多种符合 IEC 61131-3 标准的平台，使其能够适配不同品牌的 PLC 硬件，打破了厂商锁定（Vendor Lock-in）的壁垒。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;为什么需要-fb4d-应用场景&quot;&gt;为什么需要 FB4D？（应用场景）&lt;/h2&gt;

&lt;p&gt;在以下场景中，传统的 ST 语言编写会变得极其痛苦，而 FB4D 提供了高效的替代方案：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;复杂数学运算&lt;/strong&gt;：如矩阵运算、快速傅里叶变换 (FFT) 或高级滤波算法。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自定义协议解析&lt;/strong&gt;：当需要处理非标准、变长的数据包时，Pascal 的记录类型 (Record) 和指针操作比 ST 灵活得多。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态机管理&lt;/strong&gt;：构建具有数十个状态的复杂有限状态机 (FSM) 时，FB4D 的结构化语法使代码更易读、易维护。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大规模数据处理&lt;/strong&gt;：在 PLC 内部实现简单的数据库索引或复杂的查找表。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;实例演示-构建一个带限幅的积分累加器&quot;&gt;实例演示：构建一个带限幅的积分累加器&lt;/h2&gt;

&lt;p&gt;为了展示 FB4D 的逻辑思路，我们假设需要实现一个功能块：&lt;strong&gt;输入一个实时值，对其进行积分累加，但结果必须限制在指定的最小值和最大值之间。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;传统-st-语言写法-较为冗长&quot;&gt;传统 ST 语言写法（较为冗长）&lt;/h3&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;IF (i_Value &amp;gt; 0) THEN
    q_Accumulator := q_Accumulator + i_Value;
END_IF;

IF (q_Accumulator &amp;gt; i_MaxLimit) THEN
    q_Accumulator := i_MaxLimit;
ELSIF (q_Accumulator &amp;lt; i_MinLimit) THEN
    q_Accumulator := i_MinLimit;
END_IF;
&lt;/pre&gt;
&lt;h3 id=&quot;使用-fb4d-风格的逻辑实现&quot;&gt;使用 FB4D 风格的逻辑实现&lt;/h3&gt;

&lt;p&gt;在 FB4D 的框架下，你可以定义一个更加结构化的功能块，将配置参数与运行状态分离：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;(* 定义功能块结构 *)
FUNCTION_BLOCK FB_LimitedIntegrator
VAR_INPUT
    rValue : REAL;          (* 当前输入值 *)
    rMax   : REAL;          (* 上限 *)
    rMin   : REAL;          (* 下限 *)
    bReset : BOOL;         (* 重置信号 *)
END_VAR
VAR_OUTPUT
    rAccumulated : REAL;    (* 累加结果 *)
END_VAR
VAR
    fInternalSum : REAL;    (* 内部状态变量 *)
END_VAR

(* 实现逻辑 *)
BEGIN
    IF bReset THEN
        fInternalSum := 0;
    ELSE
        fInternalSum := fInternalSum + rValue;
        
        (* 使用内置的限幅逻辑 *)
        IF fInternalSum &amp;gt; rMax THEN
            fInternalSum := rMax;
        ELSE IF fInternalSum &amp;lt; rMin THEN
            fInternalSum := rMin;
        END_IF;
    END_IF;
    
    rAccumulated := fInternalSum;
END;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;实例分析：&lt;/strong&gt;
通过 FB4D 的组织方式，该逻辑被封装为一个独立的、可移植的组件。在主程序中，你只需要声明 &lt;code&gt;fbTempSensor : FB_LimitedIntegrator;&lt;/code&gt; 即可在不同温度传感器之间复用同一套逻辑，而无需重复编写 &lt;code&gt;IF-THEN&lt;/code&gt; 语句。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;如何开始使用-fb4d&quot;&gt;如何开始使用 FB4D？&lt;/h2&gt;

&lt;p&gt;如果你希望在自己的项目中集成 FB4D，可以参考以下步骤：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;克隆仓库&lt;/strong&gt;：
&lt;code&gt;git clone https://github.com/SchneiderInfosystems/FB4D.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;环境配置&lt;/strong&gt;：
检查你的 PLC 编程软件是否支持导入标准 IEC 61131-3 的库文件或源代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定义数据结构&lt;/strong&gt;：
在 FB4D 的定义文件中规划你的 &lt;code&gt;VAR_INPUT&lt;/code&gt; 和 &lt;code&gt;VAR_OUTPUT&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编译与部署&lt;/strong&gt;：
将编写的 Pascal 逻辑通过 FB4D 转换层编译为 PLC 可执行的二进制文件或 ST 源代码，并下载至控制器。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;Pascal FB4D 不仅仅是一个代码库，它代表了一种&lt;strong&gt;“将软件工程思维引入工业控制”&lt;/strong&gt;的尝试。它解决了 PLC 编程中“灵活性”与“稳定性”之间长期存在的矛盾。&lt;/p&gt;

&lt;p&gt;对于那些需要处理复杂逻辑、追求代码极致复用，且不希望被传统 PLC 编程语言限制的工程师来说，FB4D 提供了一个强大的工具集，让 PLC 真正具备了处理高级计算任务的能力。&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 06:42:15 +0800</pubDate></item><item><title>Pascal-如何在Delphi中快速实现二维码扫描与生成？详解DelphiZXingQRCode集成指南</title><link>https://zelig.cn/delphi/1121.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/07/20260711111548yrqwxkknrk.svg&quot; alt=&quot;Pascal-如何在Delphi中快速实现二维码扫描与生成？详解DelphiZXingQRCode集成指南&quot;&gt;&lt;/p&gt;&lt;h3 id=&quot;项目概述&quot;&gt;项目概述&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DelphiZXingQRCode&lt;/strong&gt; 是一个基于著名的 Java ZXing (Zebra Crossing) 库移植而来的 Pascal/Delphi 版本。它为 Delphi 开发者提供了一套完整的解决方案，用于生成和解析多种类型的条形码（Barcode）和二维码（QRCode）。&lt;/p&gt;

&lt;p&gt;在当前的移动应用和企业级软件开发中，二维码已成为连接物理世界与数字世界的桥梁。该项目通过将成熟的 ZXing 算法引入 Delphi 生态，使得开发者无需依赖复杂的第三方 DLL 或昂贵的商业组件，即可在 Windows、Android、iOS 等多平台实现高效的码制处理。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;核心功能特性&quot;&gt;核心功能特性&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全方位的码制支持&lt;/strong&gt;：

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;二维码&lt;/strong&gt;：支持 QR Code（最常用）、Data Matrix、Aztec。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一维码&lt;/strong&gt;：支持 EAN-8, EAN-13, Code 39, Code 128, ITF, UPC-A, UPC-E 等主流标准。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;双向处理能力&lt;/strong&gt;：

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;生成（Encoding）&lt;/strong&gt;：将字符串或二进制数据转换为图像文件或位图。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;识别（Decoding）&lt;/strong&gt;：通过分析图像像素，快速还原出隐藏的文本信息。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨平台兼容性&lt;/strong&gt;：

&lt;ul&gt;
&lt;li&gt;完美适配 Delphi 的多平台编译器，支持在桌面端和移动端运行。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;轻量级与高性能&lt;/strong&gt;：

&lt;ul&gt;
&lt;li&gt;纯 Pascal 实现，无需外部运行时依赖，部署简单，执行速度快。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h3 id=&quot;快速上手实例&quot;&gt;快速上手实例&lt;/h3&gt;

&lt;p&gt;为了让开发者快速掌握该库的使用，以下分为&lt;strong&gt;二维码生成&lt;/strong&gt;和&lt;strong&gt;二维码识别&lt;/strong&gt;两个典型场景的实现方案。&lt;/p&gt;

&lt;h4 id=&quot;场景一-生成一个二维码图像&quot;&gt;场景一：生成一个二维码图像&lt;/h4&gt;

&lt;p&gt;生成二维码的核心逻辑是将文本输入到编码器，然后将生成的矩阵转换为图像。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;uses
  ZXing.QRCode, 
  Vcl.Graphics; // 如果是FMX请使用 FMX.Graphics

procedure GenerateMyQRCode(const AText: string; const AFileName: string);
var
  QRCode: TZXingQRCode;
  Bmp: TBitmap;
begin
  QRCode := TZXingQRCode.Create;
  try
    // 1. 设置编码参数
    QRCode.Text := AText;
    QRCode.QuietZone := 4; // 设置静区宽度
    
    // 2. 生成位图
    // 注意：根据具体版本，可能需要调用 Generate方法或直接访问结果属性
    Bmp := QRCode.Generate; 
    try
      // 3. 保存到本地
      Bmp.SaveToFile(AFileName);
    finally
      Bmp.Free;
    end;
  finally
    QRCode.Free;
  end;
end;

// 调用示例
GenerateMyQRCode(&amp;#39;https://github.com/foxitsoftware/DelphiZXingQRCode&amp;#39;, &amp;#39;my_qr.png&amp;#39;);
&lt;/pre&gt;
&lt;h4 id=&quot;场景二-识别-扫描二维码图像&quot;&gt;场景二：识别/扫描二维码图像&lt;/h4&gt;

&lt;p&gt;识别过程则是将图像文件加载到解码器中，提取其包含的字符串。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;uses
  ZXing.QRCode, 
  Vcl.Graphics;

function DecodeMyQRCode(const AFileName: string): string;
var
  QRCodeReader: TZXingQRCodeReader;
  Bmp: TBitmap;
begin
  Result := &amp;#39;&amp;#39;;
  QRCodeReader := TZXingQRCodeReader.Create;
  try
    Bmp := TBitmap.Create;
    try
      // 1. 加载需要识别的图片
      Bmp.LoadFromFile(AFileName);
      
      // 2. 执行解码
      // Decode方法会分析图像并返回识别到的文本
      Result := QRCodeReader.Decode(Bmp);
    finally
      Bmp.Free;
    end;
  finally
    QRCodeReader.Free;
  end;
end;

// 调用示例
ShowMessage(DecodeMyQRCode(&amp;#39;my_qr.png&amp;#39;));
&lt;/pre&gt;
&lt;hr&gt;

&lt;h3 id=&quot;关键技术细节分析&quot;&gt;关键技术细节分析&lt;/h3&gt;

&lt;h4 id=&quot;1-图像预处理&quot;&gt;1. 图像预处理&lt;/h4&gt;

&lt;p&gt;在实际应用中，识别率往往取决于图像质量。DelphiZXingQRCode 在解码前会对图像进行灰度化处理。如果你在处理低对比度或光线不足的图片，建议在调用 &lt;code&gt;Decode&lt;/code&gt; 之前，先使用 Delphi 的图像处理函数提高对比度或进行二值化处理。&lt;/p&gt;

&lt;h4 id=&quot;2-内存管理&quot;&gt;2. 内存管理&lt;/h4&gt;

&lt;p&gt;由于图像处理涉及大量的像素操作，建议在循环处理大量二维码时，严格遵守 &lt;code&gt;try...finally&lt;/code&gt; 结构，确保 &lt;code&gt;TBitmap&lt;/code&gt; 和 &lt;code&gt;TZXingQRCode&lt;/code&gt; 对象被及时释放，避免内存泄漏。&lt;/p&gt;

&lt;h4 id=&quot;3-性能优化建议&quot;&gt;3. 性能优化建议&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;尺寸缩放&lt;/strong&gt;：在识别超大分辨率图片时，建议先将图片等比例缩小到 500x500 像素左右，这样可以显著提升解码速度且不影响识别率。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多线程处理&lt;/strong&gt;：对于需要批量扫描图片的场景，建议将 &lt;code&gt;Decode&lt;/code&gt; 过程放入 &lt;code&gt;TTask&lt;/code&gt; 或 &lt;code&gt;TThread&lt;/code&gt; 中，避免阻塞主界面 UI。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h3 id=&quot;常见问题与解决方案-faq&quot;&gt;常见问题与解决方案 (FAQ)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: 为什么识别某些二维码失败？&lt;/strong&gt;
&lt;strong&gt;A:&lt;/strong&gt; 常见原因包括：
*   &lt;strong&gt;静区不足&lt;/strong&gt;：二维码四周没有足够的白色留白。
*   &lt;strong&gt;畸变严重&lt;/strong&gt;：拍摄角度过于倾斜。
*   &lt;strong&gt;分辨率过低&lt;/strong&gt;：图像模糊导致像素点无法精准定位。
*   &lt;strong&gt;解决方案&lt;/strong&gt;：尝试在生成时增加 &lt;code&gt;QuietZone&lt;/code&gt;，或在识别前对图像进行裁剪。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: 如何支持中文内容？&lt;/strong&gt;
&lt;strong&gt;A:&lt;/strong&gt; ZXing 默认支持 UTF-8 编码。在 Delphi 中，请确保输入字符串为 Unicode 格式，并在生成时确认编码设置正确，以避免在其他设备扫描时出现乱码。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;总结&quot;&gt;总结&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;DelphiZXingQRCode&lt;/code&gt; 为 Delphi 开发者提供了一个极其便捷的工具集，将复杂的计算机视觉算法封装成了简单的类库。无论是开发一个简单的资产管理系统、移动端签到应用，还是企业内部的文档索引系统，该项目都能提供稳定且高效的支持。&lt;/p&gt;

&lt;p&gt;对于追求快速开发且不希望依赖外部重量级库的开发者来说，这是一个极佳的选择。&lt;/p&gt;
</description><pubDate>Wed, 22 Jul 2026 01:55:15 +0800</pubDate></item><item><title>go-# 突破LLM执行禁区：深度解析 Kubernetes 官方 agent-sandbox，构建安全的 AI 代码执行沙箱</title><link>https://zelig.cn/golang/1120.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142646bmuwodgiso.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h2 id=&quot;什么是-agent-sandbox&quot;&gt;什么是 agent-sandbox？&lt;/h2&gt;

&lt;p&gt;在 LLM（大语言模型）驱动的 Agent 时代，&lt;strong&gt;“代码解释器”（Code Interpreter）&lt;/strong&gt; 已经成为核心能力。无论是数据分析、自动化运维还是复杂计算，Agent 都会生成 Python 或 Shell 脚本并尝试执行。&lt;/p&gt;

&lt;p&gt;然而，直接在宿主机或普通容器中运行 AI 生成的代码是极其危险的。AI 可能会产生幻觉，生成 &lt;code&gt;rm -rf /&lt;/code&gt; 这样的破坏性指令，或者被恶意诱导执行远程攻击代码。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;agent-sandbox&lt;/code&gt;&lt;/strong&gt; 是由 Kubernetes SIGs 组织发起的一个开源项目，旨在为 AI Agent 提供一个&lt;strong&gt;轻量级、高隔离、快速启动&lt;/strong&gt;的执行环境。它通过利用现代虚拟化技术（如 gVisor 或轻量级 VM），确保 AI 生成的代码在一个受限的“沙箱”中运行，即使代码恶意地尝试逃逸或破坏系统，也不会影响到宿主机及其他业务。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;核心设计理念&quot;&gt;核心设计理念&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agent-sandbox&lt;/code&gt; 的设计目标是解决 AI 代码执行的三个核心痛点：&lt;strong&gt;安全性（Security）、低延迟（Latency）和状态管理（State Management）&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;1-强隔离性-strong-isolation&quot;&gt;1. 强隔离性 (Strong Isolation)&lt;/h3&gt;

&lt;p&gt;传统的 Docker 容器共享内核，如果攻击者能利用内核漏洞，即可实现容器逃逸。&lt;code&gt;agent-sandbox&lt;/code&gt; 倾向于使用更强的隔离层（如 gVisor），它在用户态实现了一个内核，拦截所有系统调用，从而在物理上切断了代码与宿主机内核的直接接触。&lt;/p&gt;

&lt;h3 id=&quot;2-极速启动-fast-startup&quot;&gt;2. 极速启动 (Fast Startup)&lt;/h3&gt;

&lt;p&gt;AI Agent 的交互是实时性的。如果每次执行一段 Python 代码都要启动一个完整的虚拟机（数秒甚至数十分钟），用户体验将极差。&lt;code&gt;agent-sandbox&lt;/code&gt; 优化了镜像加载和容器创建流程，力求在毫秒级提供可执行环境。&lt;/p&gt;

&lt;h3 id=&quot;3-临时性与快照-ephemerality-snapshots&quot;&gt;3. 临时性与快照 (Ephemerality &amp;amp; Snapshots)&lt;/h3&gt;

&lt;p&gt;Agent 的执行通常是会话式的。&lt;code&gt;agent-sandbox&lt;/code&gt; 支持创建临时沙箱，在任务完成后立即销毁，确保每次执行的纯净性，防止上一次执行的残留状态干扰下一次结果。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;技术架构分析&quot;&gt;技术架构分析&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agent-sandbox&lt;/code&gt; 充当了 LLM 编排层（如 LangChain, AutoGPT）与底层计算资源之间的&lt;strong&gt;中间件&lt;/strong&gt;。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API 层&lt;/strong&gt;：提供标准的接口，允许 Agent 提交代码片段、接收标准输出（stdout）和标准错误（stderr）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调度层&lt;/strong&gt;：管理沙箱的生命周期（创建 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 执行 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 销毁）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行时 (Runtime)&lt;/strong&gt;：集成 Kubernetes 生态，支持多种 RuntimeClass。通过配置不同的运行时，用户可以在“高性能（RunC）”与“高安全（gVisor/Kata）”之间权衡。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;资源限制&lt;/strong&gt;：严格限制 CPU、内存和网络访问，防止 AI 代码通过死循环耗尽资源或通过网络扫描内网。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;快速上手实例&quot;&gt;快速上手实例&lt;/h2&gt;

&lt;p&gt;假设你正在开发一个 AI 财务分析助手，该助手需要执行 Python 代码来计算复杂的复利模型。&lt;/p&gt;

&lt;h3 id=&quot;场景-安全执行-ai-生成的-python-脚本&quot;&gt;场景：安全执行 AI 生成的 Python 脚本&lt;/h3&gt;

&lt;h4 id=&quot;1-部署沙箱环境&quot;&gt;1. 部署沙箱环境&lt;/h4&gt;

&lt;p&gt;首先，你需要部署 &lt;code&gt;agent-sandbox&lt;/code&gt; 服务（通常部署在 K8s 集群中）。&lt;/p&gt;

&lt;h4 id=&quot;2-agent-调用流程&quot;&gt;2. Agent 调用流程&lt;/h4&gt;

&lt;p&gt;当 LLM 生成如下代码时：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;import os
# 恶意代码尝试：列出宿主机根目录
print(os.listdir(&amp;#39;/&amp;#39;)) 
# 正常计算代码
print(100 * (1.05**10))
&lt;/pre&gt;
&lt;h4 id=&quot;3-通过-api-提交执行&quot;&gt;3. 通过 API 提交执行&lt;/h4&gt;

&lt;p&gt;你的 Agent 框架将代码发送至 &lt;code&gt;agent-sandbox&lt;/code&gt; 的 API 端点：&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;curl -X POST http://agent-sandbox-service/execute \
-H &amp;#34;Content-Type: application/json&amp;#34; \
-d &amp;#39;{
  &amp;#34;language&amp;#34;: &amp;#34;python&amp;#34;,
  &amp;#34;code&amp;#34;: &amp;#34;import os; print(os.listdir(\&amp;#34;/\&amp;#34;)); print(100 * (1.05**10))&amp;#34;,
  &amp;#34;timeout&amp;#34;: 5,
  &amp;#34;memory_limit&amp;#34;: &amp;#34;128Mi&amp;#34;
}&amp;#39;
&lt;/pre&gt;
&lt;h4 id=&quot;4-沙箱内部发生的事情&quot;&gt;4. 沙箱内部发生的事情&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;创建隔离环境&lt;/strong&gt;：&lt;code&gt;agent-sandbox&lt;/code&gt; 迅速拉起一个基于 gVisor 的轻量级容器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注入代码&lt;/strong&gt;：将 Python 脚本写入该隔离环境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;受限执行&lt;/strong&gt;：

&lt;ul&gt;
&lt;li&gt;当代码执行 &lt;code&gt;os.listdir(&#039;/&#039;)&lt;/code&gt; 时，gVisor 拦截该系统调用。&lt;/li&gt;
&lt;li&gt;由于沙箱配置了根目录映射，AI 看到的 &lt;code&gt;/&lt;/code&gt; 仅仅是沙箱内部的虚拟根目录，而非宿主机的 &lt;code&gt;/&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;返回结果&lt;/strong&gt;：
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;json&quot;&gt;json&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-json prism-line-numbers&quot; data-language=&quot;json&quot;&gt;
{
 &amp;#34;stdout&amp;#34;: &amp;#34;[&amp;#39;bin&amp;#39;, &amp;#39;dev&amp;#39;, &amp;#39;etc&amp;#39;, &amp;#39;home&amp;#39;, &amp;#39;lib&amp;#39;, &amp;#39;proc&amp;#39;, &amp;#39;root&amp;#39;, &amp;#39;sys&amp;#39;, &amp;#39;tmp&amp;#39;, &amp;#39;usr&amp;#39;, &amp;#39;var&amp;#39;]\n162.8894626777442&amp;#34;,
 &amp;#34;stderr&amp;#34;: &amp;#34;&amp;#34;,
 &amp;#34;exit_code&amp;#34;: 0
}
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;销毁&lt;/strong&gt;：执行完毕，容器立即被回收，不留痕迹。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;agent-sandbox-vs-传统-docker-容器&quot;&gt;&lt;code&gt;agent-sandbox&lt;/code&gt; vs 传统 Docker 容器&lt;/h2&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;特性&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;普通 Docker 容器&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;agent-sandbox (gVisor 模式)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;内核共享&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;共享宿主机内核 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 风险高&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;独立用户态内核 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 风险极低&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;启动速度&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;较快&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;极快 (针对 Agent 优化)&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;系统调用&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;直接传递给内核&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;经过拦截和过滤&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;长期运行的服务&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;短暂、不可信的代码执行&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;资源开销&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;低&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;中低&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&quot;进阶应用场景&quot;&gt;进阶应用场景&lt;/h2&gt;

&lt;h3 id=&quot;1-自动化运维-agent-sre-bot&quot;&gt;1. 自动化运维 Agent (SRE Bot)&lt;/h3&gt;

&lt;p&gt;允许 AI Agent 在一个镜像克隆的测试环境中执行 &lt;code&gt;kubectl&lt;/code&gt; 或 &lt;code&gt;systemctl&lt;/code&gt; 命令，验证修复方案是否有效，而无需在生产环境冒险。&lt;/p&gt;

&lt;h3 id=&quot;2-数据科学沙箱&quot;&gt;2. 数据科学沙箱&lt;/h3&gt;

&lt;p&gt;为用户提供一个预装了 Pandas, NumPy, Matplotlib 的环境。AI 生成绘图代码，&lt;code&gt;agent-sandbox&lt;/code&gt; 执行并返回生成的图片文件。&lt;/p&gt;

&lt;h3 id=&quot;3-恶意代码分析-malware-analysis&quot;&gt;3. 恶意代码分析 (Malware Analysis)&lt;/h3&gt;

&lt;p&gt;安全研究员可以使用该项目快速启动一个隔离环境，运行可疑脚本并观察其行为，而无需担心感染物理机。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;agent-sandbox&lt;/code&gt; 不仅仅是一个容器包装器，它是 AI Agent 走向&lt;strong&gt;实用化&lt;/strong&gt;和&lt;strong&gt;商业化&lt;/strong&gt;的基石。在 LLM 能够编写复杂代码的今天，&lt;strong&gt;“执行权”&lt;/strong&gt;是最高危的权限。通过将执行环境从主系统剥离，并置于一个由 Kubernetes 支撑的、强隔离的沙箱中，开发者可以在享受 AI 自动化便利的同时，守住安全底线。&lt;/p&gt;

&lt;p&gt;如果你正在构建一个需要执行动态代码的 AI Agent，且对安全性有严格要求，&lt;code&gt;agent-sandbox&lt;/code&gt; 是目前 Kubernetes 生态中最值得关注的底层基础设施方案。&lt;/p&gt;
</description><pubDate>Tue, 21 Jul 2026 17:38:15 +0800</pubDate></item><item><title>go-从零构建AI编程助手：深度解析 how-to-build-a-coding-agent 实战指南</title><link>https://zelig.cn/golang/1119.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/05/20260524142629lxymgknick.svg&quot; alt=&quot;&quot;/&gt;&lt;/p&gt;
&lt;h1 id=&quot;从零构建ai编程助手-深度解析-how-to-build-a-coding-agent-实战指南&quot;&gt;从零构建AI编程助手：深度解析 how-to-build-a-coding-agent 实战指南&lt;/h1&gt;

&lt;p&gt;在 LLM（大语言模型）时代，我们已经习惯了使用 GitHub Copilot 或 Cursor。但如果你想开发一个能够自主阅读代码库、分析 Bug 并提交 PR 的“AI 软件工程师（Coding Agent）”，你会发现这不仅仅是调用一个 API 那么简单。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;how-to-build-a-coding-agent&lt;/code&gt; 这个项目提供了一套完整的、从理论到实践的路线图，旨在教会开发者如何构建一个具备&lt;strong&gt;感知-决策-执行&lt;/strong&gt;闭环的编程智能体。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;1-什么是-coding-agent&quot;&gt;1. 什么是 Coding Agent？&lt;/h2&gt;

&lt;p&gt;传统的 AI 编程助手（如简单的 Chatbot）通常是“被动”的：你输入代码，它给出建议。而 &lt;strong&gt;Coding Agent&lt;/strong&gt; 是“主动”的。它具备以下核心能力：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;环境感知&lt;/strong&gt;：能够读取文件系统、运行终端命令、搜索代码库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自主规划&lt;/strong&gt;：将复杂任务（如“修复登录页面的样式 Bug”）分解为多个子步骤。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自我修正&lt;/strong&gt;：运行测试 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 发现报错 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 分析日志 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 修改代码 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 再次测试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具调用&lt;/strong&gt;：通过 Function Calling 调用编译器、Linter 或 Git。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;2-项目核心架构分析&quot;&gt;2. 项目核心架构分析&lt;/h2&gt;

&lt;p&gt;根据该项目的指导思路，一个成熟的 Coding Agent 通常由以下四个核心模块组成：&lt;/p&gt;

&lt;h3 id=&quot;a-规划层-the-planner&quot;&gt;A. 规划层 (The Planner)&lt;/h3&gt;

&lt;p&gt;Agent 接收到任务后，不能直接写代码，而应先生成一个计划。
- &lt;strong&gt;输入&lt;/strong&gt;：用户需求 + 当前代码上下文。
- &lt;strong&gt;输出&lt;/strong&gt;：一个待办清单（Todo List）。
- &lt;strong&gt;关键技术&lt;/strong&gt;：Chain-of-Thought (CoT) 提示词工程。&lt;/p&gt;

&lt;h3 id=&quot;b-上下文检索-context-retrieval&quot;&gt;B. 上下文检索 (Context Retrieval)&lt;/h3&gt;

&lt;p&gt;LLM 的上下文窗口有限，无法将整个项目代码全部塞进去。
- &lt;strong&gt;策略&lt;/strong&gt;：使用 RAG（检索增强生成）或 符号分析。
- &lt;strong&gt;实现&lt;/strong&gt;：通过 &lt;code&gt;grep&lt;/code&gt;、&lt;code&gt;ls&lt;/code&gt; 或构建向量数据库（Vector DB）来动态寻找与当前任务相关的代码片段。&lt;/p&gt;

&lt;h3 id=&quot;c-执行层-the-executor-tool-use&quot;&gt;C. 执行层 (The Executor/Tool Use)&lt;/h3&gt;

&lt;p&gt;这是 Agent 的“手”。它需要一组安全的工具：
- &lt;code&gt;read_file(path)&lt;/code&gt;：读取文件内容。
- &lt;code&gt;write_file(path, content)&lt;/code&gt;：修改代码。
- &lt;code&gt;run_command(cmd)&lt;/code&gt;：执行 shell 命令（如 &lt;code&gt;go test ./...&lt;/code&gt;）。
- &lt;code&gt;search_code(query)&lt;/code&gt;：在代码库中搜索关键字。&lt;/p&gt;

&lt;h3 id=&quot;d-验证层-the-verifier&quot;&gt;D. 验证层 (The Verifier)&lt;/h3&gt;

&lt;p&gt;Agent 必须知道自己是否写对了。
- &lt;strong&gt;闭环机制&lt;/strong&gt;：执行测试 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 捕获 Stdout/Stderr &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 将错误反馈给 LLM &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 触发重新规划。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;3-核心实现实例-构建一个简单的-bug-修复循环&quot;&gt;3. 核心实现实例：构建一个简单的 Bug 修复循环&lt;/h2&gt;

&lt;p&gt;为了让你直观理解，我们模拟一个基于该项目理念的简化版 Go 语言 Agent 实现逻辑。&lt;/p&gt;

&lt;h3 id=&quot;场景-修复一个简单的单元测试失败&quot;&gt;场景：修复一个简单的单元测试失败&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;步骤 1：定义工具集 (Tools)&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;text&quot;&gt;text&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-text prism-line-numbers&quot; data-language=&quot;text&quot;&gt;type Tool struct {
    Name        string
    Description string
    Execute     func(args string) (string, error)
}

var Tools = []Tool{
    {
        Name: &amp;#34;read_file&amp;#34;,
        Description: &amp;#34;读取指定路径的文件内容&amp;#34;,
        Execute: func(path string) (string, error) {
            content, err := os.ReadFile(path)
            return string(content), err
        },
    },
    {
        Name: &amp;#34;run_test&amp;#34;,
        Description: &amp;#34;运行 go test 并返回结果&amp;#34;,
        Execute: func(cmd string) (string, error) {
            out, err := exec.Command(&amp;#34;go&amp;#34;, &amp;#34;test&amp;#34;, &amp;#34;./...&amp;#34;).CombinedOutput()
            return string(out), err
        },
    },
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;步骤 2：Agent 的决策循环 (The Loop)&lt;/strong&gt;
Agent 的运行逻辑是一个 &lt;code&gt;while&lt;/code&gt; 循环，直到任务完成或达到最大迭代次数：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;感知&lt;/strong&gt;：调用 &lt;code&gt;run_test&lt;/code&gt; &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 发现 &lt;code&gt;TestUserLogin&lt;/code&gt; 失败，报错 &lt;code&gt;nil pointer dereference&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析&lt;/strong&gt;：调用 &lt;code&gt;read_file&lt;/code&gt; &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 读取 &lt;code&gt;auth.go&lt;/code&gt; &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; LLM 发现第 42 行未检查 &lt;code&gt;nil&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行动&lt;/strong&gt;：调用 &lt;code&gt;write_file&lt;/code&gt; &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 插入 &lt;code&gt;if user == nil { return err }&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;验证&lt;/strong&gt;：再次调用 &lt;code&gt;run_test&lt;/code&gt; &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 测试通过 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 任务结束。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;4-构建-coding-agent-的关键挑战与对策&quot;&gt;4. 构建 Coding Agent 的关键挑战与对策&lt;/h2&gt;

&lt;p&gt;在实践 &lt;code&gt;how-to-build-a-coding-agent&lt;/code&gt; 时，你会遇到以下几个深水区：&lt;/p&gt;

&lt;h3 id=&quot;挑战一-幻觉与死循环&quot;&gt;挑战一：幻觉与死循环&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：Agent 陷入“修改 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 报错 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 还原 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 再次报错”的死循环。
&lt;strong&gt;对策&lt;/strong&gt;：
- &lt;strong&gt;引入状态记录&lt;/strong&gt;：记录已尝试过的修改方案，并在 Prompt 中告知 LLM “你之前尝试过 X 方案但失败了，请尝试其他路径”。
- &lt;strong&gt;强制终止条件&lt;/strong&gt;：设置最大迭代次数（如 10 次）。&lt;/p&gt;

&lt;h3 id=&quot;挑战二-上下文爆炸&quot;&gt;挑战二：上下文爆炸&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：代码库太大，LLM 无法处理。
&lt;strong&gt;对策&lt;/strong&gt;：
- &lt;strong&gt;分层检索&lt;/strong&gt;：先让 LLM 调用 &lt;code&gt;ls -R&lt;/code&gt; 查看目录结构 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 确定相关文件 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 仅读取相关文件。
- &lt;strong&gt;摘要化&lt;/strong&gt;：对不相关的文件仅提供函数签名而非完整实现。&lt;/p&gt;

&lt;h3 id=&quot;挑战三-安全性-the-sandbox&quot;&gt;挑战三：安全性 (The Sandbox)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;现象&lt;/strong&gt;：Agent 可能会执行 &lt;code&gt;rm -rf /&lt;/code&gt;。
&lt;strong&gt;对策&lt;/strong&gt;：
- &lt;strong&gt;容器化&lt;/strong&gt;：必须在 Docker 容器中运行 Agent 的执行层。
- &lt;strong&gt;权限限制&lt;/strong&gt;：使用非 root 用户，限制网络访问。&lt;/p&gt;

&lt;hr&gt;

&lt;h2 id=&quot;5-学习路径建议&quot;&gt;5. 学习路径建议&lt;/h2&gt;

&lt;p&gt;如果你想通过这个项目真正掌握 Coding Agent 的开发，建议采取以下步骤：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第一阶段（基础）&lt;/strong&gt;：实现一个简单的 LLM Wrapper，能够通过 Function Calling 调用本地的 &lt;code&gt;ls&lt;/code&gt; 和 &lt;code&gt;cat&lt;/code&gt; 命令。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第二阶段（闭环）&lt;/strong&gt;：构建一个“测试-修复”循环。给它一个有 Bug 的小项目，让它通过运行测试来自动修复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第三阶段（增强）&lt;/strong&gt;：引入代码索引（如使用 &lt;code&gt;tree-sitter&lt;/code&gt; 解析 AST 或使用 &lt;code&gt;chromadb&lt;/code&gt; 做向量检索），提升它在大型项目中的定位能力。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第四阶段（工程化）&lt;/strong&gt;：增加人类干预环节（Human-in-the-loop），在 Agent 执行 &lt;code&gt;write_file&lt;/code&gt; 之前要求用户点击“确认”。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;how-to-build-a-coding-agent&lt;/code&gt; 不仅仅是一个代码库，它提供的是一种&lt;strong&gt;工程思维&lt;/strong&gt;：将 LLM 从一个“聊天机器人”转变为一个“能够操作工具的智能体”。&lt;/p&gt;

&lt;p&gt;通过将 &lt;strong&gt;LLM 的推理能力&lt;/strong&gt; &lt;span class=&quot;math inline&quot;&gt;\(\text{+}\)&lt;/span&gt; &lt;strong&gt;确定性的工具调用&lt;/strong&gt; &lt;span class=&quot;math inline&quot;&gt;\(\text{+}\)&lt;/span&gt; &lt;strong&gt;严谨的验证机制&lt;/strong&gt; 结合在一起，你就可以构建出真正能够提升生产力的 AI 编程助手。&lt;/p&gt;
</description><pubDate>Tue, 21 Jul 2026 16:30:15 +0800</pubDate></item><item><title>Pascal snap7：用 Delphi/FreePascal 轻松掌控西门子 PLC 的工业通信指南</title><link>https://zelig.cn/delphi/1118.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/07/20260711111519gjknjwsful.svg&quot; alt=&quot;Pascal snap7：用 Delphi/FreePascal 轻松掌控西门子 PLC 的工业通信指南&quot;&gt;&lt;/p&gt;&lt;h1 id=&quot;pascal-snap7-项目深度解析与实战指南&quot;&gt;Pascal snap7 项目深度解析与实战指南&lt;/h1&gt;

&lt;h2 id=&quot;1-项目概述&quot;&gt;1. 项目概述&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pascal snap7&lt;/strong&gt; 是一个为 Delphi 和 Free Pascal 开发者量身定制的开源库，它通过对强大的 C 语言库 &lt;code&gt;snap7&lt;/code&gt; 的封装，使得 Pascal 语言能够直接与西门子 S7 系列 PLC（包括 S7-300, S7-400, S7-1200, S7-1500）进行高效的 TCP/IP 通信。&lt;/p&gt;

&lt;p&gt;在工业自动化领域，西门子 PLC 占据主导地位。传统的通信方式往往依赖于复杂的 OPC 服务器或昂贵的专用驱动。&lt;code&gt;snap7&lt;/code&gt; 的出现提供了一种轻量级的替代方案，而 &lt;code&gt;Pascal snap7&lt;/code&gt; 则将这种能力带入了 Pascal 生态，让开发者能够快速构建 SCADA 系统、数据采集软件或工业监控面板。&lt;/p&gt;

&lt;h3 id=&quot;核心特性&quot;&gt;核心特性&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全协议支持&lt;/strong&gt;：支持 S7 通信协议，无需在 PLC 端编写复杂的通信块。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨平台潜力&lt;/strong&gt;：得益于 Free Pascal (FPC) 的特性，理论上可支持 Windows 和 Linux。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高性能&lt;/strong&gt;：直接调用底层 C 库，确保了数据传输的实时性和低延迟。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;灵活的读写&lt;/strong&gt;：支持对 DB 块（数据块）、输入区（I）、输出区（Q）以及标志位（M）的随机访问。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h2 id=&quot;2-快速上手指南&quot;&gt;2. 快速上手指南&lt;/h2&gt;

&lt;h3 id=&quot;2-1-环境准备&quot;&gt;2.1 环境准备&lt;/h3&gt;

&lt;p&gt;在使用 &lt;code&gt;Pascal snap7&lt;/code&gt; 之前，你需要准备以下环境：
1. &lt;strong&gt;IDE&lt;/strong&gt;：Delphi (10.x 或更高版本) 或 Free Pascal / Lazarus。
2. &lt;strong&gt;二进制库&lt;/strong&gt;：你需要 &lt;code&gt;snap7.dll&lt;/code&gt; (Windows) 或 &lt;code&gt;libsnap7.so&lt;/code&gt; (Linux)。这些文件通常由原生的 &lt;a href=&quot;https://github.com/snap7-assoc/snap7&quot;&gt;snap7 C 库&lt;/a&gt; 编译而来。
3. &lt;strong&gt;PLC 配置&lt;/strong&gt;（至关重要）：
   - &lt;strong&gt;允许 PUT/GET 通信&lt;/strong&gt;：在 TIA Portal 中，进入 PLC 属性 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 保护与安全 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 勾选“允许来自远程伙伴的 PUT/GET 访问”。
   - &lt;strong&gt;禁用优化访问&lt;/strong&gt;：对于 DB 块，必须右键属性 &lt;span class=&quot;math inline&quot;&gt;\(\rightarrow\)&lt;/span&gt; 取消勾选“优化块访问”，否则无法通过绝对地址访问。&lt;/p&gt;

&lt;h3 id=&quot;2-2-安装步骤&quot;&gt;2.2 安装步骤&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;将 &lt;code&gt;snap7&lt;/code&gt; 单元文件（&lt;code&gt;.pas&lt;/code&gt;）添加到你的项目路径中。&lt;/li&gt;
&lt;li&gt;将 &lt;code&gt;snap7.dll&lt;/code&gt; 放置在可执行文件（&lt;code&gt;.exe&lt;/code&gt;）所在的同一目录下。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h2 id=&quot;3-核心代码实例&quot;&gt;3. 核心代码实例&lt;/h2&gt;

&lt;p&gt;以下是一个完整的示例，演示如何连接 PLC、读取 DB 块中的整数值以及写入一个布尔值。&lt;/p&gt;

&lt;h3 id=&quot;3-1-基础连接与读取示例&quot;&gt;3.1 基础连接与读取示例&lt;/h3&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;uses
  SysUtils, 
  snap7; // 引入 snap7 单元

procedure PLC_Communication_Demo;
var
  Client: TS7Client;
  ReadBuffer: array[0..10] of Byte;
  Value: Integer;
begin
  // 1. 创建客户端实例
  Client := TS7Client.Create;
  try
    try
      // 2. 连接到 PLC (IP地址, 机架号, 插槽号)
      // 通常 S7-1200/1500 的机架为 0, 插槽为 1
      Client.ConnectTo(&amp;#39;192.168.0.1&amp;#39;, 0, 1);
      
      if Client.Connected then
      begin
        Writeln(&amp;#39;连接成功！&amp;#39;);

        // 3. 读取 DB1.DBW0 (读取 2 个字节，即一个 Word/Integer)
        // 参数：DB号, 起始地址, 长度, 缓冲区
        Client.DBRead(1, 0, 2, ReadBuffer);
        
        // 将字节数组转换为整数 (注意：西门子是大端字节序 Big-Endian)
        Value := (ReadBuffer[0] shl 8) or ReadBuffer[1];
        Writeln(&amp;#39;读取到的值为: &amp;#39;, Value);
      end;
    except
      on E: Exception do
        Writeln(&amp;#39;通信错误: &amp;#39;, E.Message);
    end;
  finally
    Client.Disconnect;
    Client.Free;
  end;
end;
&lt;/pre&gt;
&lt;h3 id=&quot;3-2-写入数据示例&quot;&gt;3.2 写入数据示例&lt;/h3&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;procedure WriteToPLC;
var
  Client: TS7Client;
  WriteBuffer: array[0..0] of Byte;
begin
  Client := TS7Client.Create;
  try
    Client.ConnectTo(&amp;#39;192.168.0.1&amp;#39;, 0, 1);
    
    // 准备写入数据：将 DB1.DBX0.0 设为 True
    // DBX 是位访问，但 snap7 写入通常以字节为单位
    WriteBuffer[0] := 1; // 00000001 (二进制)
    
    // 写入 DB1, 从地址 0 开始, 写入 1 个字节
    Client.DBWrite(1, 0, 1, WriteBuffer);
    
    Writeln(&amp;#39;写入成功！&amp;#39;);
  finally
    Client.Disconnect;
    Client.Free;
  end;
end;
&lt;/pre&gt;
&lt;hr&gt;

&lt;h2 id=&quot;4-关键技术点解析&quot;&gt;4. 关键技术点解析&lt;/h2&gt;

&lt;h3 id=&quot;4-1-字节序-endianness-问题&quot;&gt;4.1 字节序（Endianness）问题&lt;/h3&gt;

&lt;p&gt;西门子 PLC 使用 &lt;strong&gt;Big-Endian&lt;/strong&gt;（大端序），而 Windows/Intel 平台使用 &lt;strong&gt;Little-Endian&lt;/strong&gt;（小端序）。
- &lt;strong&gt;读取时&lt;/strong&gt;：当你读取一个 16 位整数（Word）时，接收到的 &lt;code&gt;ReadBuffer[0]&lt;/code&gt; 是高位，&lt;code&gt;ReadBuffer[1]&lt;/code&gt; 是低位。
- &lt;strong&gt;处理方法&lt;/strong&gt;：使用位移操作 &lt;code&gt;(HighByte shl 8) or LowByte&lt;/code&gt; 或调用专门的字节交换函数。&lt;/p&gt;

&lt;h3 id=&quot;4-2-数据类型映射表&quot;&gt;4.2 数据类型映射表&lt;/h3&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;S7 类型&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;长度 (Bytes)&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Pascal 类型&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;备注&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;

&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Bool&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1 bit&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Boolean&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;需通过掩码处理字节中的特定位&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Byte&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Byte&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;直接映射&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Int / Word&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Integer / Word&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;需处理大端序&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;DInt / DWord&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;LongInt / Cardinal&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;需处理大端序&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Real&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Single&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;遵循 IEEE 754 标准&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;hr&gt;

&lt;h2 id=&quot;5-性能优化建议&quot;&gt;5. 性能优化建议&lt;/h2&gt;

&lt;p&gt;在开发实际的工业软件时，建议采取以下策略以提高稳定性：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;异步通信&lt;/strong&gt;：不要在主 UI 线程中调用 &lt;code&gt;ConnectTo&lt;/code&gt; 或 &lt;code&gt;DBRead&lt;/code&gt;，否则在网络波动时界面会卡死。请使用 &lt;code&gt;TThread&lt;/code&gt; 或 &lt;code&gt;TTask&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;批量读取&lt;/strong&gt;：避免在循环中多次调用 &lt;code&gt;DBRead&lt;/code&gt; 读取单个变量。建议一次性读取一个较大的缓冲区（例如读取 DB1.DBW0 到 DB1.DBW100），然后在内存中解析，这样能极大减少网络往返时间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;心跳检测&lt;/strong&gt;：建立一个定时器，每隔 1-5 秒读取一个 PLC 内部的标志位，用于实时监测连接状态。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异常处理&lt;/strong&gt;：工业现场电磁干扰严重，网络丢包常见。务必将所有通信代码包裹在 &lt;code&gt;try...except&lt;/code&gt; 块中，并实现自动重连机制。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;6-总结&quot;&gt;6. 总结&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Pascal snap7&lt;/code&gt; 为 Delphi 和 Lazarus 开发者打开了通往西门子 PLC 世界的大门。它摒弃了繁琐的中间件，直接通过 TCP 协议与硬件对话。无论是开发简单的设备监控工具，还是复杂的工厂 MES 系统，该项目都提供了一个极其稳健且高效的底层通信基础。&lt;/p&gt;
</description><pubDate>Tue, 21 Jul 2026 10:14:15 +0800</pubDate></item><item><title>DelphiWebsockets：用 Pascal 赋予 Delphi 实时通信能力，打破 HTTP 限制的 WebSocket 终极方案</title><link>https://zelig.cn/delphi/1117.html</link><description>&lt;p&gt;&lt;img src=&quot;/zb_users/upload/2026/07/20260711111503ihruxymcel.svg&quot; alt=&quot;DelphiWebsockets：用 Pascal 赋予 Delphi 实时通信能力，打破 HTTP 限制的 WebSocket 终极方案&quot;&gt;&lt;/p&gt;&lt;h3 id=&quot;项目概述&quot;&gt;项目概述&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DelphiWebsockets&lt;/strong&gt; 是一个为 Delphi 和 Free Pascal 开发者量身定制的开源库，旨在简化 WebSocket 协议的实现。在传统的 Web 开发中，HTTP 协议是“请求-响应”模式，服务器无法主动向客户端推送数据。而 WebSocket 协议则建立了一个持久的双向通信通道，使得服务器能够实时地向客户端发送数据，这对于实时聊天、股票行情、在线协作工具以及实时监控面板至关重要。&lt;/p&gt;

&lt;p&gt;该项目通过对 WebSocket 握手协议的封装和数据帧的解析，让 Delphi 开发者无需深入研究复杂的 RFC 6455 协议细节，即可快速构建高性能的实时通信服务器或客户端。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;核心特性&quot;&gt;核心特性&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;全双工通信&lt;/strong&gt;：支持真正的双向实时数据传输，消除轮询（Polling）带来的高延迟和资源浪费。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;轻量级设计&lt;/strong&gt;：基于 Pascal 语言特性，内存占用低，执行效率高，适合部署在资源受限的服务器环境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步处理&lt;/strong&gt;：支持异步消息处理机制，确保在处理大量并发连接时，主界面或主逻辑不会出现卡死现象。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协议兼容性&lt;/strong&gt;：严格遵循 WebSocket 标准，能够与现代浏览器（Chrome, Firefox, Edge 等）以及其他语言编写的 WebSocket 客户端无缝对接。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;易于集成&lt;/strong&gt;：提供简洁的类接口，通过简单的事件驱动模式即可完成消息的接收与发送。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;h3 id=&quot;适用场景&quot;&gt;适用场景&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实时聊天系统&lt;/strong&gt;：构建私聊、群聊功能，实现消息的秒级送达。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实时数据看板&lt;/strong&gt;：如金融交易软件的实时K线图、工业设备的实时传感器数据监控。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多人协作工具&lt;/strong&gt;：如共享白板、在线文档编辑的同步机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;远程控制与指令下发&lt;/strong&gt;：向连接的客户端实时发送控制指令，实现远程开关或配置更新。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;游戏后端&lt;/strong&gt;：处理快节奏的游戏状态同步。&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;h3 id=&quot;快速上手实例&quot;&gt;快速上手实例&lt;/h3&gt;

&lt;p&gt;为了让您快速理解 &lt;code&gt;DelphiWebsockets&lt;/code&gt; 的工作原理，以下是一个构建简易 WebSocket 服务器的逻辑示例。&lt;/p&gt;

&lt;h4 id=&quot;1-环境准备&quot;&gt;1. 环境准备&lt;/h4&gt;

&lt;p&gt;首先，将 &lt;code&gt;DelphiWebsockets&lt;/code&gt; 源代码添加到你的 Delphi 项目路径中，并在 &lt;code&gt;uses&lt;/code&gt; 单元中引用相关组件。&lt;/p&gt;

&lt;h4 id=&quot;2-创建服务器实例&quot;&gt;2. 创建服务器实例&lt;/h4&gt;

&lt;p&gt;你需要实例化一个 WebSocket 服务器类，并指定监听的端口。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;var
  WSServer: TWebsocketServer;
begin
  WSServer := TWebsocketServer.Create(nil);
  WSServer.Port := 8080; // 设置监听端口为 8080
  WSServer.Active := True; // 启动服务器
end;
&lt;/pre&gt;
&lt;h4 id=&quot;3-处理客户端连接与消息&quot;&gt;3. 处理客户端连接与消息&lt;/h4&gt;

&lt;p&gt;通过绑定事件处理器，你可以捕获客户端的连接请求以及发送过来的消息。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;procedure TMyForm.WSServerOnMessage(Sender: TObject; Client: TWebsocketClient; const Message: string);
begin
  // 当收到客户端消息时触发
  MemoLog.Lines.Add(&amp;#39;收到客户端消息: &amp;#39; + Message);
  
  // 回应客户端：原路返回（Echo 模式）
  Client.Send(&amp;#39;服务器已收到你的消息: &amp;#39; + Message);
end;

procedure TMyForm.WSServerOnConnect(Sender: TObject; Client: TWebsocketClient);
begin
  MemoLog.Lines.Add(&amp;#39;新客户端已连接！&amp;#39;);
  Client.Send(&amp;#39;欢迎连接到 Delphi WebSocket 服务器！&amp;#39;);
end;
&lt;/pre&gt;
&lt;h4 id=&quot;4-向所有客户端广播&quot;&gt;4. 向所有客户端广播&lt;/h4&gt;

&lt;p&gt;如果你需要实现一个群聊功能，可以遍历当前所有连接的客户端并发送消息。&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;pascal&quot;&gt;pascal&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;prism-highlight prism- language-pascal prism-line-numbers&quot; data-language=&quot;pascal&quot;&gt;procedure TMyForm.btnBroadcastClick(Sender: TObject);
var
  Client: TWebsocketClient;
begin
  for Client in WSServer.Clients do
  begin
    Client.Send(&amp;#39;系统广播：服务器将在 5 分钟后重启，请及时保存数据。&amp;#39;);
  end;
end;
&lt;/pre&gt;
&lt;hr&gt;

&lt;h3 id=&quot;技术深度解析&quot;&gt;技术深度解析&lt;/h3&gt;

&lt;h4 id=&quot;握手过程-the-handshake&quot;&gt;握手过程 (The Handshake)&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;DelphiWebsockets&lt;/code&gt; 内部处理了从 HTTP 升级到 WebSocket 的关键步骤。当客户端发送 &lt;code&gt;Upgrade: websocket&lt;/code&gt; 请求时，该库会自动计算 &lt;code&gt;Sec-WebSocket-Accept&lt;/code&gt; 响应头（通过 SHA-1 散列和 Base64 编码），确保连接的安全升级。&lt;/p&gt;

&lt;h4 id=&quot;数据帧处理-framing&quot;&gt;数据帧处理 (Framing)&lt;/h4&gt;

&lt;p&gt;WebSocket 传输的数据不是简单的文本，而是被包裹在“帧”中的。该项目实现了对数据帧的掩码（Masking）处理和解掩码操作，确保数据在传输过程中符合协议规范，并能正确区分文本帧（Text Frame）和二进制帧（Binary Frame）。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;常见问题与优化建议&quot;&gt;常见问题与优化建议&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. 如何处理高并发连接？&lt;/strong&gt;
对于大规模连接，建议将 WebSocket 处理逻辑移至多线程环境，或者结合 Delphi 的 &lt;code&gt;TThread&lt;/code&gt; 或 &lt;code&gt;Parallel Programming Library (PPL)&lt;/code&gt;，避免在主线程中进行耗时的 IO 操作。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 如何实现心跳检测（Heartbeat）？&lt;/strong&gt;
为了防止防火墙或代理服务器自动断开长时间不活动的连接，建议每隔 30-60 秒发送一个 &lt;code&gt;Ping&lt;/code&gt; 帧。&lt;code&gt;DelphiWebsockets&lt;/code&gt; 支持发送控制帧，你可以通过定时器触发心跳包。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. 安全性考虑&lt;/strong&gt;
如果项目需要部署在公网，建议在 &lt;code&gt;DelphiWebsockets&lt;/code&gt; 前端部署一个 Nginx 反向代理，并配置 SSL 证书，将 &lt;code&gt;ws://&lt;/code&gt; 升级为 &lt;code&gt;wss://&lt;/code&gt;（WebSocket Secure），以保证数据的加密传输。&lt;/p&gt;

&lt;hr&gt;

&lt;h3 id=&quot;总结&quot;&gt;总结&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;DelphiWebsockets&lt;/code&gt; 为 Pascal 开发者提供了一个高效、简洁的实时通信基石。它将复杂的底层协议细节封装起来，让开发者能够专注于业务逻辑的实现。无论你是想为旧的 Delphi 桌面应用增加实时同步功能，还是想构建一个现代化的实时 Web 后端，这个项目都提供了一个极具性价比的起点。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;项目地址回顾：&lt;/strong&gt; &lt;a href=&quot;https://github.com/andremussche/DelphiWebsockets&quot;&gt;https://github.com/andremussche/DelphiWebsockets&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Tue, 21 Jul 2026 10:09:15 +0800</pubDate></item></channel></rss>