一般情况下,您不用修改三三平台的核心组件,你只需要把三三当作物联网底座或中台,利用三三平台提供的灵活而强大的协议、丰富的 API、强大的应用管理机制,去构建您的物联网应用。
如果您一定要修改核心组件,三三平台采用微服务架构实现了各组件的完全解耦,您可以基于三三已有的组件修改,或用自己编写并替换三三平台的某个组件实现您的需求。
三三的开发遵循一系列规范和协议,包括 API 接口规范、 MQTT 接口、目录规范、配置文件规范。另外,我们还提供了方便您开发服务的核心库。
API 接口规范
请求响应
主要介绍API的请求结构
1、请求URI {URI-scheme}://{Endpoint}/api/{micro-server}/{resource-path} 例:http://ssiot.cc:9000/api/device/find http://ssiot.cc:9000/api/alarm/find
参数 | 说明 |
---|---|
URI-scheme | 请求协议,http/https |
Endpoint | 提供REST服务的端点域名/ip+端口,三三云平台为 ssiot.cc:9000 |
micro-server | 微服务节点名称,参考前面章节的系统模块说明(少量接口特例,具体以接口文档为准) |
resource-path | 资源路径,按实际业务访问不同,如对配置的查列表/详情、增、改、删,定义为config/find、get、add、modify、remove |
2、请求方法
方法 | 说明 |
---|---|
GET | 查询,请求服务器或返回特定资源 |
POST | 增删改,修改或删除特定资源,或执行特殊操作如设备控制下发 |
3、响应内容
{
"code": 200,
"message": "操作成功",
"result": {},
"success": true,
"timestamp": 1684823798374
}
字段 | 说明 |
---|---|
code | 错误码 |
message | 成功/失败消息 |
result | 响应结果,json对象,可为空,也可包含分页信息 |
success | 成功/失败标志 |
timestamp | 响应时间戳 |
错误码
错误码 | 说明 |
---|---|
200 | 成功 |
0 | 自定义异常 |
201 | 操作失败 |
202 | 请求参数错误 |
203 | 用户名不正确 |
204 | 密码不正确 |
205 | 添加失败 |
206 | 更新失败 |
207 | 删除失败 |
208 | 修改失败 |
209 | 查找失败 |
210 | 上传失败 |
211 | 不被识别的手机号 |
300 | 创建进程失败 |
301 | 进程启动失败 |
302 | 进程重复 |
303 | 进程不存在 |
304 | 进程删除失败 |
305 | 缺少进程文件或目录 |
API 接口清单
MQTT 接口
业务主题
主题 | 说明 |
---|---|
/san/data/handle | 已处理消息数据流转 |
/san/event/device/login、/san/event/device/logout | 上线触发业务 |
/san/event/device/delete | 设备操作触发业务 |
/san/event/device/add | 设备操作触发业务 |
/san/alarm/notify | 告警通知主题 |
/san/data/forward | 数据mq转发主题 |
三三物联协议
详见三三物联协议
SDK
我们提供了 ssiot-core, 高效便捷的开发框架ssiot-core,方便开发者完成集成开发
项目结构
下载源代码, 除了 ui 目录外,其它目录均为后端模块目录
# Gitee仓库
git clone https://gitee.com/sansaniot/ssiot.git
以下以 device 模块为例说明项目目录结果
./
├─cmd # 服务命令
│ └─system # 系统服务模块,如系统初始化
├─common # 通用模块
│ ├─constant # 常量
│ ├─database # 数据库通用业务,如数据初始化、自动生成表
│ ├─dto # 业务DTO数据定义
│ ├─enums # 系统枚举
│ ├─middleware # 应用中间件
│ │ ├─jwt # JWT 鉴权中间
│ │ ├─log # Log中间件
│ │ └─secure # Secure认证中间
│ └─utils # Util工具包
├─config # 配置管理
│ └─settings.yml # 统一配置文件(微服务端口、数据库、MQTT、Redis等)
├─internal # 业务应用模块
│ ├─device # 模块入口
│ │ ├─router # HTTP router
│ │ ├─apis # 业务 API逻辑
│ │ ├─models # 业务model(数据库模型处理,完成前端页面与数据库接口对象转换)
│ │ ├─service # 业务Service,对接apis,调用各models进行业务整合,返回业务数据
│ │ ├─ws # WebSocket API
│ | └─start.go # 模块启动入口
| ├─data # 模块数据处理
├─ Makefile # Makefile文件
├─ README.md # README 介绍
├─ main.go # 程序入口
配置文件
service: #微服务地址
sansan: #微服务管理服务
port: 9500
ipdb: ./config/ip2region.xdb #ip解析数据库
admin: #权限服务
port: 9510
filepath: ./data/assets #资源文件路径
device: #设备管理服务
port: 9520
alarm: #告警服务
port: 9530
notify: #通知服务
port: 9540
forward: #转发服务
port: 9550
ssiot: #公共配置
http: #http应用访问地址
host: 0.0.0.0
logger: #日志配置
path: ./log
stdout: ''
level: trace
enableddb: true #系统日志记录
mqtt: #后台mqtt服务地址
host: 127.0.0.1
port: 9010
user:
passwd:
timeout: 3
database: #数据库连接
driver: postgres
source: host=127.0.0.1 user=postgres password=123456 dbname=sansaniot port=9020 sslmode=disable TimeZone=Asia/Shanghai
cache: #缓存中间件
redis: #redis
addr: 127.0.0.1:9030
password: '123456'
db: 0
jwt: #接口鉴权jwt配置
secret: ssiot2023
timeout: 3600
代码示例
internal/device/start.go
import (
"gitee.com/sansaniot/ssiot-core/facade/env"
"gitee.com/sansaniot/ssiot-core/facade/httpserver"
"gitee.com/sansaniot/ssiot-core/httpmvc"
"gitee.com/sansaniot/ssiot-core/httpmvc/api"
"github.com/shafreeck/cortana"
...
)
func Start() error {
// 启动参数格式自定义, 如./device -c config/settings.yml
args := struct {
CfgFile string `cortana:"--config, -c, , config file"`
}{}
cortana.Parse(&args)
if args.CfgFile != "" {
constant.ConfigFile = args.CfgFile
}
// 如有需要,向内核注册自己需要的中间件
// 限流
httpserver.RegisterMiddlewareFunction(secure.Sentinel())
// 自动增加requestId
httpserver.RegisterMiddlewareFunction(secure.RequestId(httpmvc.TrafficKey))
// 获取上下文提供的日志
httpserver.RegisterMiddlewareFunction(api.SetRequestLogger)
// 请求日志记录到文件
//httpserver.RegisterMiddlewareFunction(log.LoggerToFile())
// 自定义错误处理
httpserver.RegisterMiddlewareFunction(log.CustomError)
// NoCache is a middleware function that appends headers
httpserver.RegisterMiddlewareFunction(secure.NoCache)
// 跨域处理
httpserver.RegisterMiddlewareFunction(secure.Options)
// Secure is a middleware function that appends security
httpserver.RegisterMiddlewareFunction(secure.Secure)
// 必须,初始化引擎
httpserver.InitEngine(constant.ConfigFile)
env.DefaultConfig.Http.Port = env.ConfigOperator.GetInt64("service.device.port")
// 启动系统业务
system.InitSystemBiz()
// 可选,初始化JWT验证方法组
jwtMiddleware, _ := jwt.AuthInit()
// 必须,向内核注册自己的业务模块路由,如不使用中间件,则使用InitRouters方法
httpserver.InitAuthRouters(router.RouterCheckRole, jwtMiddleware)
httpserver.InitAuthRouters(ruleRouter.RuleRouters, jwtMiddleware)
httpserver.InitRouters(router.RouterNoCheckRole)
// 启动HTTP服务器
_ = httpserver.Run()
return nil
}
internal/device/router/device.go
import (
jwt "gitee.com/sansaniot/ssiot-core/httpmvc/jwtauth"
"github.com/gin-gonic/gin"
"ssdevice/internal/device/apis"
)
func init() {
RouterCheckRole = append(RouterCheckRole, registerDeviceRouter)
}
// v1 注册系统路由, authMiddleware jwt鉴权
func registerDeviceRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
api := apis.Device{}
// 设备
r := v1.Group("/api/device").Use(authMiddleware.MiddlewareFuncWithOutValidate())
{
r.GET("/find", api.FindList)
...
}
internal/device/apis/device.go
import (
"gitee.com/sansaniot/ssiot-core/httpmvc/api"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"ssdevice/common/enums"
"ssdevice/internal/device/models"
"ssdevice/internal/device/models/command"
"ssdevice/internal/device/models/query"
"ssdevice/internal/device/service"
)
// 添加设备
func (e Device) AddDevice(c *gin.Context) {
// 请求参数
req := command.DeviceInsertReq{}
// 业务service
s := &service.Device{}
// 上下文
err := e.MakeContext(c).
MakeOrm().
Bind(&req, binding.JSON).
MakeService(&s.Service).
Errors
if err != nil {
e.Logger.Error(err)
e.Fail(0, err.Error())
return
}
// service注入实体
s.SetAllModel()
// 用户信息
req.LoadUser(c)
// 执行
var result models.SysDev
if err, result = s.AddDevice(&req); err != nil {
e.Logger.Error(err)
e.Fail(0, err.Error())
return
}
// 返回
e.Data(result)
}