第11章 Request 与 Response
本章大纲
- Request 的传统含义
- SAI 中的信息输入
- Web Request
- Device Request
- Sensor Event
- System Event
- Information
- Response
- Expression
- Action Result
- Request → SAI
- SAI → Response
- 完整运行示例
11.1 Request 的传统含义
在传统 Web Framework 中,Request 通常表示:
客户端向服务器发送的一次 HTTP 请求。
例如浏览器访问:
GET /user/profile?id=1001
服务器收到:
HTTP Request
Request 中可能包含:
Method
URL
Query
POST Data
Headers
Cookies
Files
IP
传统 Web 程序一般是:
Browser
↓
HTTP Request
↓
Router
↓
Controller
↓
Business Logic
↓
Response
↓
Browser
这是非常典型的 Web Framework 模式。
但是 SAI Framework 面临的问题更大。
因为 SAI 并不只面对浏览器。
11.2 SAI 中的信息输入
SAI 的输入不能简单定义成:
HTTP Request
因为一个人工个体可能面对:
人
设备
传感器
环境
其他系统
内部事件
因此在 SAI Framework 中,需要把更大的概念定义为:
Information Receiving —— 信息接收。
可以表示为:
External World
│
▼
Information
│
▼
SAI
信息来源可以包括:
Information
├── Human
├── Web
├── Device
├── Sensor
├── System
├── Environment
└── Other SAI
因此:
Request 是一种输入形式,Information 才是 SAI 内部统一处理的输入对象。
这是本章最重要的概念。
11.3 Web Request
Web Request 是 SAI 最容易理解的一种输入。
例如用户访问:
GET /temperature
传统 Framework:
HTTP Request
↓
Controller
↓
Response
SAI Framework:
HTTP Request
↓
Request
↓
Information
↓
Perception
↓
Cognition
↓
Reasoning
↓
Decision
↓
Behavior
↓
Expression
↓
Response
因此 Web Request 只是 SAI 输入链路的最外层。
例如:
GET /temperature?room=A
可以转换为:
$information = array(
'type' => 'web_request',
'source' => 'browser',
'content' => array(
'action' => 'get_temperature',
'room' => 'A'
)
);
然后进入 SAI。
11.4 Device Request
设备也可以向 SAI 发送信息。
例如一个智能设备发送:
temperature = 32
这不是浏览器 Request。
可以定义为:
Device Request
例如:
TemperatureDevice
↓
Device Request
↓
Information
↓
SAI
设备信息可能包含:
device_id
device_type
state
value
time
location
例如:
$information = array(
'type' => 'device_request',
'source' => 'temperature_sensor',
'content' => array(
'temperature' => 32
)
);
SAI 不需要把所有外部输入都强行变成 HTTP Request。
这就是 SAI 与 Web Framework 的重要区别。
11.5 Sensor Event
传感器通常不是传统意义上的 Request。
它可能不断产生事件:
Sensor
↓
Event
↓
Information
↓
SAI
例如:
DistanceSensor
检测到:
distance = 0.8m
产生:
Sensor Event
例如:
$event = array(
'type' => 'sensor_event',
'source' => 'distance_sensor',
'content' => array(
'distance' => 0.8
)
);
之后:
Sensor Event
↓
Information
↓
Perception
↓
Element
↓
Object
↓
Relation
例如 SAI 可以形成:
Object: Obstacle
Property: distance
Value: 0.8m
因此 Sensor Event 是 SAI 感知外部世界的重要输入方式。
11.6 System Event
SAI 内部或者外部系统也可以产生事件。
例如:
timer
device_connected
device_disconnected
task_finished
error
warning
state_changed
这些都可以进入 Information 层。
例如:
$event = array(
'type' => 'system_event',
'source' => 'device_manager',
'content' => array(
'event' => 'device_connected',
'device_id' => 'motor_001'
)
);
进入:
System Event
↓
Information
↓
SAI
所以 SAI 的输入机制可以形成:
Information Input
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Request Event State
│ │ │
Web/Device Sensor/System Device/System
11.7 Information
Request、Event、State 最终都需要进入统一的信息结构。
可以设计:
class Information
{
protected $type;
protected $source;
protected $content;
protected $time;
protected $context;
protected $metadata;
}
基本结构:
Information
├── type
├── source
├── content
├── time
├── context
└── metadata
例如:
$information = new Information(
'sensor_event',
'temperature_sensor',
array(
'temperature' => 32
)
);
这里的核心思想是:
不同外部输入
↓
统一 Information
↓
SAI 内部处理
例如:
Web Request ──────┐
Device Request ──┤
Sensor Event ────┤
System Event ────┼──→ Information
State Change ────┤
Human Input ─────┘
这样 SAI 的核心认知体系不需要关心输入来自浏览器还是传感器。
11.8 Response
传统 Web Framework 中:
Request
↓
Controller
↓
Response
Response 通常是:
HTML
JSON
XML
File
Redirect
但是 SAI 的输出更加广泛。
例如:
Web
API
Display
Device
Robot
Machine
因此不能简单认为:
SAI → HTTP Response
更准确的是:
SAI
↓
Output
↓
Expression / Action Result
↓
Renderer / Adapter
↓
External Output
于是:
Response
只是 SAI 输出的一种外部表现。
11.9 Expression
Expression 可以理解为:
SAI 将内部行为或结果转换为外部可表达形式的过程。
例如 SAI 内部决定:
Fan = ON
这首先是:
Decision
↓
Behavior
↓
Action
然后根据不同环境产生不同 Expression。
Web:
Fan ON
↓
HTML / JSON
API:
{
"device": "fan",
"action": "on"
}
设备:
FanAdapter
↓
Device Command
↓
Fan
所以:
Internal Action
↓
Expression
↓
External Representation
Expression 不等于 HTML。
HTML 只是 Expression 的一种表现形式。
11.10 Action Result
Action Result 是执行行为之后得到的结果。
例如:
Decision
↓
Fan.turnOn()
↓
Action
↓
Device
↓
Result
成功:
success
失败:
failed
也可能:
partial
timeout
rejected
unknown
例如:
$result = array(
'success' => true,
'action' => 'fan.turnOn',
'device' => 'fan_001',
'time' => time()
);
Action Result 可以重新进入 SAI:
Action
↓
Device
↓
Action Result
↓
Feedback
↓
Information
↓
Perception
于是闭环形成:
Decision
↓
Behavior
↓
Action
↓
External World
↓
Result
↓
Feedback
↓
Information
这也是 SAI 与普通 Request/Response 程序的重要区别之一。
11.11 Request → SAI
现在可以建立完整的 Web 输入过程。
例如用户发送:
GET /temperature
第一阶段:
Browser
↓
HTTP Request
第二阶段:
HTTP Request
↓
Request Object
第三阶段:
Request
↓
Information
第四阶段:
Information
↓
Perception
第五阶段:
Perception
↓
Cognition
之后:
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
最终:
Behavior
↓
Expression
↓
Renderer
↓
Response
完整流程:
Browser
↓
Request
↓
Information
↓
Perception
↓
Element
↓
Object
↓
Relation
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Expression
↓
Renderer
↓
Response
↓
Browser
11.12 SAI → Response
反方向需要更加准确地理解。
SAI 并不是直接:
Decision
↓
Response
而是:
Decision
↓
Behavior
↓
Action / Expression
↓
Renderer / Adapter
↓
External Output
Web 场景:
Decision
↓
Behavior
↓
Expression
↓
WebRenderer
↓
HTTP Response
设备场景:
Decision
↓
Behavior
↓
Action
↓
DeviceAdapter
↓
Device
API 场景:
Decision
↓
Expression
↓
ApiRenderer
↓
JSON Response
因此:
SAI Output
│
┌────────┴────────┐
▼ ▼
Expression Action
│ │
▼ ▼
Renderer Adapter
│ │
▼ ▼
Web Device
API Robot
UI Machine
11.13 Request 与 Information 的关系
需要特别区分两个概念。
Request
Request 是外部输入形式。
例如:
HTTP Request
Device Request
API Request
Information
Information 是SAI 内部统一的信息对象。
所以:
Request
↓
Information
↓
SAI
而不是:
Request = Information
可以理解为:
外部世界
↓
各种输入形式
↓
Information
↓
SAI内部认知体系
11.14 Response 与 Expression 的关系
同样:
Response
是外部系统能够接收的一种结果。
而:
Expression
是 SAI 内部对行为、结果或信息进行外部表达的机制。
所以:
Expression
↓
Renderer
↓
Response
例如:
Expression
{
action: "fan_on"
}
WebRenderer:
{
"success": true,
"action": "fan_on"
}
而 DeviceAdapter:
fan_001 → ON
同一个内部行为可以拥有不同外部表现。
11.15 完整运行示例
下面建立一个最简单的:
Web Request → Information → SAI → Response
案例。
说明:以下代码是本章教程示例,用于说明 Request、Information、Response 的关系,不代表当前已经实际部署或验证。
目录:
sai-request-demo/
│
├── app/
│ ├── Core/
│ │ ├── Request.php
│ │ └── Response.php
│ │
│ └── Information/
│ └── Information.php
│
├── bootstrap.php
└── index.php
11.15.1 Request.php
<?php
namespace SAI\Core;
class Request
{
protected $method;
protected $path;
protected $query;
public function __construct(
$method,
$path,
array $query = array()
) {
$this->method = $method;
$this->path = $path;
$this->query = $query;
}
public function getMethod()
{
return $this->method;
}
public function getPath()
{
return $this->path;
}
public function getQuery($name)
{
if (isset($this->query[$name])) {
return $this->query[$name];
}
return null;
}
}
11.15.2 Information.php
<?php
namespace SAI\Information;
class Information
{
protected $type;
protected $source;
protected $content;
protected $time;
public function __construct(
$type,
$source,
$content
) {
$this->type = $type;
$this->source = $source;
$this->content = $content;
$this->time = time();
}
public function getType()
{
return $this->type;
}
public function getSource()
{
return $this->source;
}
public function getContent()
{
return $this->content;
}
public function getTime()
{
return $this->time;
}
}
11.15.3 Response.php
<?php
namespace SAI\Core;
class Response
{
protected $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function send()
{
header('Content-Type: application/json');
echo json_encode(
$this->data
);
}
}
11.15.4 bootstrap.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
spl_autoload_register(function ($class) {
$prefix = 'SAI\\';
if (strpos($class, $prefix) !== 0) {
return;
}
$relative = substr(
$class,
strlen($prefix)
);
$file = __DIR__
. '/app/'
. str_replace(
'\\',
'/',
$relative
)
. '.php';
if (is_file($file)) {
require_once $file;
}
});
11.15.5 index.php
<?php
require_once __DIR__ . '/bootstrap.php';
use SAI\Core\Request;
use SAI\Core\Response;
use SAI\Information\Information;
$request = new Request(
isset($_SERVER['REQUEST_METHOD'])
? $_SERVER['REQUEST_METHOD']
: 'CLI',
isset($_SERVER['REQUEST_URI'])
? $_SERVER['REQUEST_URI']
: '/',
$_GET
);
$information = new Information(
'web_request',
'browser',
array(
'method' => $request->getMethod(),
'path' => $request->getPath(),
'action' => $request->getQuery('action')
)
);
$response = new Response(
array(
'success' => true,
'request' => array(
'method' => $request->getMethod(),
'path' => $request->getPath()
),
'information' => array(
'type' => $information->getType(),
'source' => $information->getSource(),
'content' => $information->getContent()
)
)
);
$response->send();
例如访问:
/index.php?action=temperature
按照代码逻辑,预期会形成类似:
{
"success": true,
"request": {
"method": "GET",
"path": "/index.php?action=temperature"
},
"information": {
"type": "web_request",
"source": "browser",
"content": {
"method": "GET",
"path": "/index.php?action=temperature",
"action": "temperature"
}
}
}
这里依然是代码推导出的预期结果,不是本次实际运行验证结果。
11.16 从 Request 进入真正的 SAI
上面的案例只完成了:
Request
↓
Information
↓
Response
真正的 SAI Framework 还需要继续:
Request
↓
Information
↓
Perception
↓
Element
↓
Object
↓
Relation
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Expression
↓
Response
例如:
GET /fan?action=cooling
进入 SAI 后可能形成:
Information
{
action = cooling
}
经过认知:
Object = Fan
Property = state
结合环境事实:
Room.temperature = 32
Fan.state = OFF
Person.state = PRESENT
再通过规则:
IF
temperature > 30
AND
person = present
AND
fan = off
THEN
fan.turnOn()
经过:
Reasoning
↓
Decision
↓
Behavior
↓
Action
得到:
Fan.turnOn()
如果是 Web:
Action Result
↓
Expression
↓
WebRenderer
↓
Response
如果是真实设备:
Action
↓
DeviceAdapter
↓
Fan
↓
Feedback
↓
Information
这就开始形成 SAI 的闭环。
11.17 SAI 的 Request/Response 与传统 Web 的根本区别
传统 Web:
Request
↓
Controller
↓
Business Logic
↓
Response
SAI:
Request / Event / Sensor / Device
↓
Information
↓
Perception
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Expression / Action
↓
Renderer / Adapter
↓
Response / Device Action
因此:
Request/Response 是 SAI 与外部世界连接的一种工程接口,而不是 SAI 的完整运行机制。
这也是为什么 SAI 可以运行在:
Web
CLI
Robot
Vehicle
Industrial Device
Sensor System
Embedded Environment
等不同环境中。
11.18 本章核心关系
本章可以最终压缩成四个核心概念:
输入
Request
Event
Sensor
State
↓
统一
Information
↓
SAI 内部处理
Perception
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
输出
Expression
Action Result
↓
外部表现
Response
Device
Robot
Machine
完整结构:
External World
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
Request Event Sensor
│ │ │
└───────────────────┼───────────────────┘
▼
Information
│
▼
Perception
│
▼
Cognition
│
┌────┴────┐
▼ ▼
Memory Reasoning
│ │
└────┬────┘
▼
Decision
│
▼
Behavior
│
┌─────────┴─────────┐
▼ ▼
Expression Action
│ │
▼ ▼
Renderer Adapter
│ │
▼ ▼
Response Device
│ │
└─────────┬─────────┘
▼
Feedback
│
▼
Information
本章小结
第11章最重要的是建立 Request、Information、Response 与 SAI 核心体系之间的边界。
传统 Web Framework:
Request
↓
Controller
↓
Business Logic
↓
Response
SAI Framework:
Request / Event / Sensor / Device
↓
Information
↓
Perception
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Expression / Action
↓
Renderer / Adapter
↓
Response / Device
↓
Feedback
↓
Information
因此可以确定:
Request 是外部输入形式,Information 是 SAI 内部统一输入对象;Response 是外部输出形式,Expression 和 Action Result 是 SAI 内部输出结果。
同时:
Request ≠ Information
Response ≠ Expression
Controller ≠ Central
这三个区别非常重要。
到这里,第8~11章已经形成一条完整的 Framework 基础链:
Application
│
▼
Bootstrap
│
▼
Container
│
▼
Request
│
▼
Information
│
▼
SAI Runtime
下一章进入 第12章 Controller 时,就可以进一步明确:
Request
↓
Controller
↓
Information
↓
SAI
以及为什么:
Controller 是外部输入控制层,而 Central 是 Individual 内部协调中心,两者虽然都具有“控制”作用,但处于完全不同的架构位置。