# 封装器路由器原理剖析 首先HTTP不需要封装器。 消息通过客户端发出流到服务器控制器中需要经历以下过程。 客户端->封装器(PACK)->中间件(MIDD)->路由器(ROUTE) 反之服务器要发送消息需要通过下面过程 服务器->封装器(PACK)->客户端 SD的封装器和路由器可以在不同端口上配置,所以SD可以做到不同端口不同协议,但是业务代码是统一的,框架会自动转换正确的协议。 ## 封装器 封装器主要进行协议头封装和数据的序列化和反序列化过程。 框架提供的封装器有: * EofJsonPack * NonJsonPack * LenJsonPack * MqttPack 其中Json是指序列化工具使用的是json,Eof代表协议头是EOF类型的,Len代表协议头是LEN类型的,参考 [Swoole编程指南-EOF协议](Swoole编程指南-EOF协议.md) [Swoole编程指南-固定包头协议](Swoole编程指南-固定包头协议.md) 而Non是指没有协议头封装,这个适用于WebSocket,因为websocket有自带的协议封装,不需要我们画蛇添足。 Pack中有4个主要函数: * encode 添加协议头 * decode 移除协议头 * pack 序列化后添加协议头 * unPack 移除协议头后反序列化 如果需要自定义封装器可以参考框架提供的几种。 同时可以参考这篇文章 [物联网自定义协议](物联网自定义协议.md) ## 路由器 框架仅仅提供了一个NormalRoute路由器,路由器会拿到封装器unPack后的结果,请注意这里NormalRoute需要的是一个stdClass并不是一个数组类型。如果需要是数组类型的,需要自定义Route和Pack。 * handleClientData 传递给路由器unPack后的结果,并验证下是否合适 * getControllerName 获取控制器名 * getMethodName 获取方法名 NormalRoute通过getControllerName和getMethodName方法处理unPack后数据中的值并返回正确的框架可以识别的Controller名称和对应的方法名。 **ControllerName为Controllers文件夹中文件的名称** **MethodName为Controller类中public标识的方法名** * getParams 获取参数必须为数组类型 如果getParams提供了返回值,将会作为控制器method的参数 * errorHandle Route任何地方抛出异常都会调用,可以在这里关闭连接。 下面介绍的是HTTP用到的函数 * handleClientRequest 处理HTTP请求设置client_data供getControllerName和getMethodName使用。 * errorHttpHandle Route任何地方抛出异常都会调用,可以在这里输出结果或者重定向。(仅仅HTTP) **HTTP一般结合中间件完成整个流程,比如NormalHttpMiddleware将在Route处理前完成静态内容的指定,和一些特殊情况的处理**