mirror of
https://gitee.com/XM-GO/PandaX.git
synced 2026-04-23 02:48:34 +08:00
128 lines
3.5 KiB
Go
128 lines
3.5 KiB
Go
package httpserver
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"github.com/emicklei/go-restful/v3"
|
||
"io"
|
||
"net"
|
||
"net/http"
|
||
"pandax/iothub/hook_message_work"
|
||
"pandax/iothub/netbase"
|
||
"pandax/pkg/global"
|
||
"pandax/pkg/global/model"
|
||
"pandax/pkg/rule_engine/message"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
type HookHttpService struct {
|
||
HookService *hook_message_work.HookService
|
||
}
|
||
|
||
var (
|
||
activeConnections sync.Map
|
||
)
|
||
|
||
func InitHttpHook(addr string, hs *hook_message_work.HookService) {
|
||
server := NewHttpServer(addr)
|
||
service := &HookHttpService{
|
||
HookService: hs,
|
||
}
|
||
container := server.Container
|
||
ws := new(restful.WebService)
|
||
ws.Path("/api/v1").Produces(restful.MIME_JSON)
|
||
ws.Route(ws.POST("/{token}/{pathType}").Filter(basicAuthenticate).To(service.hook))
|
||
container.Add(ws)
|
||
|
||
server.srv.ConnState = func(conn net.Conn, state http.ConnState) {
|
||
// 断开连接
|
||
switch state {
|
||
case http.StateHijacked, http.StateClosed:
|
||
etoken, _ := activeConnections.Load(conn.RemoteAddr().String())
|
||
if etoken != nil {
|
||
data := netbase.CreateConnectionInfo(message.DisConnectMes, "http", conn.RemoteAddr().String(), conn.RemoteAddr().String(), etoken.(*model.DeviceAuth))
|
||
activeConnections.Delete(conn.RemoteAddr().String())
|
||
service.HookService.MessageCh <- data
|
||
}
|
||
}
|
||
}
|
||
err := server.Start(context.TODO())
|
||
if err != nil {
|
||
global.Log.Error("IOTHUB HTTP服务启动错误", err)
|
||
} else {
|
||
global.Log.Infof("HTTP IOTHUB HOOK Start SUCCESS,Server listen: %s", addr)
|
||
}
|
||
}
|
||
|
||
// 获取token进行认证
|
||
func basicAuthenticate(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) {
|
||
token := req.PathParameter("token")
|
||
auth := netbase.Auth(token)
|
||
if !auth {
|
||
resp.Write([]byte("认证错误"))
|
||
return
|
||
}
|
||
chain.ProcessFilter(req, resp)
|
||
}
|
||
|
||
func (hhs *HookHttpService) hook(req *restful.Request, resp *restful.Response) {
|
||
token := req.PathParameter("token")
|
||
pathType := req.PathParameter("pathType")
|
||
if token == "" || pathType == "" {
|
||
resp.Write([]byte("路径未识别token,或上报类型"))
|
||
return
|
||
}
|
||
var upData map[string]interface{}
|
||
err := req.ReadEntity(&upData)
|
||
if err != nil {
|
||
resp.Write([]byte("解析上报参数失败"))
|
||
return
|
||
}
|
||
etoken := &model.DeviceAuth{}
|
||
etoken.GetDeviceToken(token)
|
||
_, ok := activeConnections.Load(req.Request.RemoteAddr)
|
||
// 是否需要添加设备上线通知
|
||
if !ok {
|
||
activeConnections.Store(req.Request.RemoteAddr, etoken)
|
||
data := netbase.CreateConnectionInfo(message.ConnectMes, "http", req.Request.RemoteAddr, req.Request.RemoteAddr, etoken)
|
||
hhs.HookService.MessageCh <- data
|
||
}
|
||
marshal, _ := json.Marshal(upData)
|
||
data := &netbase.DeviceEventInfo{
|
||
Datas: string(marshal),
|
||
DeviceAuth: etoken,
|
||
DeviceId: etoken.DeviceId,
|
||
}
|
||
switch pathType {
|
||
case Row:
|
||
ts := time.Now().Format("2006-01-02 15:04:05.000")
|
||
data.Type = message.RowMes
|
||
data.Datas = fmt.Sprintf(`{"ts": "%s","rowdata": "%s"}`, ts, data.Datas)
|
||
case Telemetry:
|
||
telemetryData := netbase.UpdateDeviceTelemetryData(data.Datas)
|
||
if telemetryData == nil {
|
||
resp.Write([]byte("解析遥测失败"))
|
||
return
|
||
}
|
||
bytes, _ := json.Marshal(telemetryData)
|
||
data.Type = message.TelemetryMes
|
||
data.Datas = string(bytes)
|
||
case Attributes:
|
||
attributesData := netbase.UpdateDeviceAttributesData(data.Datas)
|
||
if attributesData == nil {
|
||
resp.Write([]byte("解析属性失败"))
|
||
return
|
||
}
|
||
bytes, _ := json.Marshal(attributesData)
|
||
data.Datas = string(bytes)
|
||
data.Type = message.AttributesMes
|
||
default:
|
||
resp.Write([]byte("路径上报类型错误"))
|
||
return
|
||
}
|
||
hhs.HookService.MessageCh <- data
|
||
io.WriteString(resp, "ok")
|
||
}
|