Websocket Support, Geofencing Nearby Hook Support

This commit is contained in:
Supan Adit Pratama 2019-12-27 17:26:50 +07:00
parent e02e1513fa
commit 98ca740a7e
2 changed files with 98 additions and 16 deletions

96
main.go
View File

@ -1,51 +1,66 @@
package main package main
import ( import (
"fmt"
"github.com/gin-contrib/cors" "github.com/gin-contrib/cors"
"github.com/gin-contrib/sse" "github.com/gin-contrib/sse"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-redis/redis" "github.com/go-redis/redis"
"github.com/gorilla/websocket"
"github.com/rs/xid" "github.com/rs/xid"
"github.com/supanadit/geo-smart-system/model" "github.com/supanadit/geo-smart-system/model"
"github.com/supanadit/geo-smart-system/model/tile38" "github.com/supanadit/geo-smart-system/model/tile38"
"log"
"net/http" "net/http"
) )
func main() { func main() {
port := "8080"
client := redis.NewClient(&redis.Options{ client := redis.NewClient(&redis.Options{
Addr: "localhost:9851", Addr: "192.168.99.100:9851",
}) })
r := gin.Default() r := gin.Default()
r.Use(cors.Default()) r.Use(cors.Default())
r.GET("/id/get/unique", func(c *gin.Context) { r.GET("/id/get/unique", func(c *gin.Context) {
id := xid.New() id := xid.New()
c.JSON(200, gin.H{"id": id.String()}) c.JSON(200, gin.H{"id": id.String()})
}) })
r.POST("/point/set", func(c *gin.Context) { r.POST("/point/set", func(c *gin.Context) {
var location model.Location var location model.Location
err := c.BindJSON(&location) err := c.BindJSON(&location)
client.Do("SET", location.Type, location.Id, "POINT", location.Lat, location.Lng) client.Do("SET", location.Type, location.Id, "POINT", location.Lat, location.Lng)
var status map[string]interface{} var status map[string]interface{}
var httpStatus int
if err != nil { if err != nil {
status = gin.H{"status": "Unknown Error"} status = gin.H{"status": "Unknown Error"}
httpStatus = http.StatusInternalServerError
} else { } else {
status = gin.H{"status": "Ok"} status = gin.H{"status": "Ok"}
httpStatus = http.StatusOK
} }
c.Writer.Header().Set("Content-Type", "application/json") c.Writer.Header().Set("Content-Type", "application/json")
c.JSON(http.StatusOK, status) c.JSON(httpStatus, status)
}) })
r.POST("/point/unset", func(c *gin.Context) { r.POST("/point/unset", func(c *gin.Context) {
var location model.Location var location model.Location
err := c.BindJSON(&location) err := c.BindJSON(&location)
client.Do("DEL", location.Type, location.Id) client.Do("DEL", location.Type, location.Id)
var status map[string]interface{} var status map[string]interface{}
var httpStatus int
if err != nil { if err != nil {
status = gin.H{"status": "Unknown Error"} status = gin.H{"status": "Unknown Error"}
httpStatus = http.StatusInternalServerError
} else { } else {
status = gin.H{"status": "Ok"} status = gin.H{"status": "Ok"}
httpStatus = http.StatusOK
} }
c.Writer.Header().Set("Content-Type", "application/json") c.Writer.Header().Set("Content-Type", "application/json")
c.JSON(http.StatusOK, status) c.JSON(httpStatus, status)
}) })
r.GET("/point/get", func(c *gin.Context) { r.GET("/point/get", func(c *gin.Context) {
@ -57,21 +72,70 @@ func main() {
r.GET("/point/get/stream", func(c *gin.Context) { r.GET("/point/get/stream", func(c *gin.Context) {
w := c.Writer w := c.Writer
t := c.DefaultQuery("type", "user") t := c.DefaultQuery("type", "user")
r := c.DefaultQuery("request", "")
data, _ := tile38.FromScan(client, t) data, _ := tile38.FromScan(client, t)
if r == "sse" {
w.Header().Set("Content-Type", "text/event-stream") _ = sse.Encode(w, sse.Event{
w.Header().Set("Cache-Control", "no-cache") Event: "message",
w.Header().Set("Connection", "keep-alive") Data: data,
_ = sse.Encode(w, sse.Event{ })
Event: "message",
Data: data,
})
} else {
c.JSON(http.StatusOK, data)
}
}) })
r.POST("/detection/set", func(c *gin.Context) {
var detection model.Detection
err := c.BindJSON(&detection)
hookID := "HOOK-" + xid.New().String()
fmt.Printf("Set HOOK with ID : %s \n", hookID)
hookURL := "http://192.168.99.1:" + port + "/detection/call"
client.Do("SETHOOK", hookID, hookURL, "NEARBY", detection.Type, "FENCE", "DETECT", "enter", "COMMANDS", "set", "POINT", detection.Lat, detection.Lng)
var status map[string]interface{}
var httpStatus int
if err != nil {
status = gin.H{"status": "Unknown Error"}
httpStatus = http.StatusInternalServerError
} else {
status = gin.H{"status": "Ok"}
httpStatus = http.StatusOK
}
c.Writer.Header().Set("Content-Type", "application/json")
c.JSON(httpStatus, status)
})
r.GET("/detection/call", func(c *gin.Context) {
fmt.Println("Called")
c.JSON(200, gin.H{"status": "test"})
})
r.GET("/ws", func(c *gin.Context) {
websocketHandler(c.Writer, c.Request)
})
r.Static("/public", "./public") r.Static("/public", "./public")
r.Static("/assets", "./assets") r.Static("/assets", "./assets")
_ = r.Run()
_ = r.Run(":" + port)
}
var websocketUpgrade = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func websocketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := websocketUpgrade.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
for {
t, msg, err := conn.ReadMessage()
if err != nil {
break
}
fmt.Printf("Received : %s \n", msg)
_ = conn.WriteMessage(t, []byte("OK"))
}
} }

18
model/detection.go Normal file
View File

@ -0,0 +1,18 @@
package model
type Trigger string
const (
inside Trigger = "inside" // when an object is inside the specified area
outside Trigger = "outside" // when an object is outside the specified area
enter Trigger = "enter" // when an object that was not previously in the fence has entered the area
exit Trigger = "exit" // when an object that was previously in the fence has exited the area
cross Trigger = "cross" // when an object that was not previously in the fence has entered and exited the area
)
type Detection struct {
Type string `json:"type"`
Lat string `json:"lat"`
Lng string `json:"lng"`
TriggerType []Trigger `json:"trigger_type"`
}