package main import ( "github.com/gorilla/websocket" uuid "github.com/satori/go.uuid" "math/rand" "strconv" "strings" "time" ) type MonfloManagement struct { clients []*ClientInfo } type ClientInfo struct { UserName string `json:"user_name"` Metadata string `json:"metadata"` Name string `json:"name"` PrivateAddr string `json:"private_addr"` PublicAddr string `json:"public_addr"` Key string `json:"key"` Bitrate int `json:"bitrate"` Formats []string `json:"formats"` //h264 h265 Stream string `json:"stream"` ClientStatus string `json:"client_status"` //online offline StreamStatus string `json:"stream_status"` //ready busy CreatedAt int64 `json:"created_at"` //1599031125 ApiKey string `json:"apikey"` //"apikey-af461547-da12-5e33-9a99-c63d9000762b" MacAddress string `json:"mac_address"` //"04ea56b3f380" Fingerprint string `json:"fingerprint"` //"fingerprint": "45c9dd6c-6925-a994-3fc3-c26cdec786ce", Id string `json:"id"` // "id": "device-4d4c9fba-4d11-5b10-b3b3-05346a7bd4d2", Client string `json:"client"` //"client": "client-8c220f6e-3432-5f41-80f2-b830f7b60658", wsConn *websocket.Conn StreamId string `json:"stream_id"` //40832596627 ClientType string `json:"client_type"` //client server } func (m *MonfloManagement) checkExist(userName string, fingerprint string) bool { if m.clients == nil { return false } for _, client := range m.clients { if client.Fingerprint == fingerprint && client.UserName == userName { return true } } return false } func (m *MonfloManagement) getClient(userName string, fingerprint string) *ClientInfo { for _, client := range m.clients { if client.Fingerprint == fingerprint && client.UserName == userName { return client } } return nil } func (m *MonfloManagement) getClientByApiKey(apiKey string) *ClientInfo { for _, client := range m.clients { if client.ApiKey == apiKey { return client } } return nil } func (m *MonfloManagement) getClientByFingerprint(fingerprint string) *ClientInfo { for _, client := range m.clients { if client.Fingerprint == fingerprint { return client } } return nil } func (m *MonfloManagement) addClient(userName string, fingerprint string) { if !m.checkExist(userName, fingerprint) { client := &ClientInfo{ UserName: userName, CreatedAt: time.Now().Unix(), ApiKey: "apikey-" + fingerprint, Fingerprint: fingerprint, Id: "device-" + fingerprint, Client: "client-" + fingerprint, ClientStatus: "offline", } m.clients = append(m.clients, client) } } func (m *MonfloManagement) addServer(clientStr string) *ClientInfo { for _, c := range m.clients { if c.Client == clientStr { return c } } client := &ClientInfo{ Client: clientStr, CreatedAt: time.Now().Unix(), } m.clients = append(m.clients, client) return client } func (m *MonfloManagement) addDevice(request AddDeviceRequest) { client := m.getClientByFingerprint(request.Fingerprint) client.Name = request.Name client.Fingerprint = request.Fingerprint client.Metadata = request.Metadata client.MacAddress = request.MacAddress if strings.Contains(request.Metadata, "\"streamer\":\"1\",") { client.ClientType = "server" } else { client.ClientType = "client" } } func (m *MonfloManagement) getPeers(userName string) map[string]PeerInfo { peers := make(map[string]PeerInfo) if m.clients == nil { return peers } for _, client := range m.clients { if client.UserName == userName { streams := make(map[string]StreamInfo) var formats = []string{"h264", "h265"} if client.Stream != "" { streams[client.Stream] = StreamInfo{ Id: client.Stream, Status: client.StreamStatus, OwnerClient: client.Client, Name: client.Name, PrivateAddr: client.PrivateAddr, PublicAddr: client.PublicAddr, Key: client.Key, Bitrate: 500000, Formats: formats, } } peers[client.Client] = PeerInfo{ Name: client.Name, Status: client.ClientStatus, //online;offline LastIP: IPInfo{ PrivateAddr: client.PrivateAddr, PublicAddr: client.PublicAddr, }, Streams: streams, } } } return peers } func (m *MonfloManagement) getDevices(userName string) []LoginResponse { var devices []LoginResponse if m.clients == nil { return devices } for _, client := range m.clients { if client.UserName == userName { device := LoginResponse{ CreatedAt: client.CreatedAt, ApiKey: client.ApiKey, MacAddress: client.MacAddress, Metadata: client.Metadata, Fingerprint: client.Fingerprint, Id: client.Id, Client: client.Client, Name: client.Name, } devices = append(devices, device) } } return devices } func (m *MonfloManagement) genId(client *ClientInfo) { id := 10000000009 + 8*rand.Int63n(5) for { if !m.checkIdExist(strconv.FormatInt(id, 10)) { break } id = 10000000009 + 8*rand.Int63n(5) } client.StreamId = strconv.FormatInt(id, 10) } func (m *MonfloManagement) genStream(client *ClientInfo) { uid, _ := uuid.NewV4() client.Stream = "stream-" + uid.String() client.StreamStatus = "ready" } func (m *MonfloManagement) checkIdExist(id string) bool { for _, c := range m.clients { if c.Id == id { return true } } return false } func (m *MonfloManagement) setOffline(clientId string) { del := -1 for i, c := range m.clients { if c.Client == clientId { if c.ApiKey == "" && c.Id == "" { del = i } c.ClientStatus = "offline" } } if del >= 0 { m.clients = append(m.clients[:del], m.clients[del+1:]...) } } func (m *MonfloManagement) getClientStream(stream string) *ClientInfo { for _, c := range m.clients { if c.Stream == stream { return c } } return nil } func (m *MonfloManagement) getClientStreamId(streamId string) *ClientInfo { for _, c := range m.clients { if c.StreamId == streamId { return c } } return nil } func (m *MonfloManagement) getUserAllClient(userName string) []*ClientInfo { var clients []*ClientInfo for _, c := range m.clients { if c.UserName == userName { clients = append(clients, c) } } return clients }