Files
PandaX/iothub/server/httpserver/hook.go
2023-11-07 16:45:23 +08:00

128 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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")
}