连接联犀服务
约 866 字大约 3 分钟
2025-03-03
本指南将详细介绍如何在自定义服务中调用联犀平台的 RPC 服务,实现设备控制、数据查询等核心功能。
📋 目录
⚠️ 前置条件
重要:请确保联犀服务已正常运行
- Docker 方式:Docker 部署教程
- 源码方式:直接运行联犀服务代码
🔧 配置初始化
1. 添加配置结构
在服务的 internal/config/config.go
中添加 RPC 客户端配置:
type Config struct {
// ... 其他配置
DmRpc conf.RpcClientConf `json:",optional"`
}
2. 配置文件设置
在 etc/xxx.yaml
中添加 RPC 连接配置:
ETCD 模式(推荐)
DmRpc:
Conf:
Timeout: 1000000
Etcd:
Hosts:
- localhost:2379
Key: dm.rpc
参考:ETCD 注册 key 可参考 dmsvr 的配置
直连模式
DmRpc:
Conf:
Timeout: 1000000
Endpoints:
- localhost:9081
注意:IP 和端口请参考 dmsvr 服务的实际监听地址
🚀 服务初始化
1. 查看接口定义
首先查看 dmsvr 的 proto 文件,找到需要调用的接口:
- 文件位置:
things/service/dmsvr/proto/dm.proto:269
- 服务名称:
DeviceInteract
2. 引入客户端
在 internal/svc/serviceContext.go
中引入并初始化客户端:
package svc
import (
"gitee.com/unitedrhino/share/ctxs"
"gitee.com/unitedrhino/share/eventBus"
"gitee.com/unitedrhino/share/utils"
"gitee.com/unitedrhino/things/service/dmsvr/client/deviceinteract"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/kv"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
"lightsvr/internal/config"
)
type ServiceContext struct {
Config config.Config
InitCtxsWare rest.Middleware
DeviceInteract deviceinteract.DeviceInteract
FastEvent *eventBus.FastEvent
Store kv.Store
NodeID int64
}
func NewServiceContext(c config.Config) *ServiceContext {
// 初始化设备交互客户端
deviceInteract := deviceinteract.NewDeviceInteract(
zrpc.MustNewClient(c.DmRpc.Conf)
)
// 获取节点 ID
nodeID := utils.GetNodeID(c.CacheRedis, c.Name)
// 初始化事件总线
fastEvent, err := eventBus.NewFastEvent(c.Event, c.Name, nodeID)
logx.Must(err)
return &ServiceContext{
Config: c,
InitCtxsWare: ctxs.InitMiddleware,
FastEvent: fastEvent,
DeviceInteract: deviceInteract,
Store: kv.NewStore(c.CacheRedis),
NodeID: nodeID,
}
}
3. 客户端位置
客户端代码位于:things/service/dmsvr/client/deviceinteract/deviceInteract.go
说明:client 目录下的代码由 proto 文件自动生成,可直接引入使用
💡 接口调用
设备控制示例
以控制设备开灯为例:
// 调用设备属性控制接口
ret, err := svcCtx.DeviceInteract.PropertyControlSend(ctx, &dm.PropertyControlSendReq{
ProductID: device.ProductID,
DeviceName: device.DeviceName,
Data: fmt.Sprintf(`{"load":%v}`, param),
})
if err != nil {
logx.Errorf("设备控制失败: %v", err)
return err
}
logx.Infof("设备控制成功: %+v", ret)
常用接口
接口名称 | 功能描述 | 使用场景 |
---|---|---|
PropertyControlSend | 属性控制 | 设备开关、参数调节 |
PropertyQuery | 属性查询 | 获取设备当前状态 |
EventReport | 事件上报 | 设备事件通知 |
ActionCall | 行为调用 | 执行设备行为 |
🎯 最佳实践
1. 错误处理
ret, err := svcCtx.DeviceInteract.PropertyControlSend(ctx, req)
if err != nil {
// 记录错误日志
logx.Errorf("RPC 调用失败: %v", err)
// 返回业务错误
return errors.New("设备控制失败")
}
2. 超时控制
// 设置上下文超时
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
ret, err := svcCtx.DeviceInteract.PropertyControlSend(ctx, req)
3. 重试机制
var ret *dm.PropertyControlSendResp
var err error
// 最多重试 3 次
for i := 0; i < 3; i++ {
ret, err = svcCtx.DeviceInteract.PropertyControlSend(ctx, req)
if err == nil {
break
}
if i < 2 {
time.Sleep(time.Duration(i+1) * time.Second)
}
}
4. 连接池配置
DmRpc:
Conf:
Timeout: 1000000
MaxRetries: 3
KeepAlive: 30s
MaxIdle: 10
IdleTimeout: 60s
🔗 相关链接
💡 提示:建议先在测试环境验证 RPC 调用,确认无误后再部署到生产环境。