func sendMessage(messageBytes []byte, retry bool) { // retry defer func() { if r := recover(); r != nil { client.Connected = false log.Print("Retrying Client Connector - ", client.Connector.ID, " ", r) time.Sleep(8 * time.Second) if retry { client.Messages = append(client.Messages, messageBytes) } } }() // connect if !client.Connected { if client.Connector.Debug { log.Print("Connecting to: " + client.Connector.Server + ":" + client.Connector.Port) } var err error client.Conn, err = net.Dial("tcp", client.Connector.Server+":"+client.Connector.Port) if err != nil { log.Print(err) } client.Connected = true } // validate key key, err := parse.MakeKey(client.Connector.Key) if err != nil { log.Print(err) } // encrypt message messageEncrypt, err := parse.Encrypt(key, messageBytes) if err != nil { log.Print(err) } // publish _, err = fmt.Fprintln(client.Conn, messageEncrypt) if err != nil { log.Print(err) client.Connected = false panic(err) } }
func (x Server) Listen(commandMsgs chan<- models.Message, connector models.Connector) { defer Recovery(connector) // estsablish connection clients := make(map[string]int) listener, err := net.Listen("tcp", ":"+connector.Port) if err != nil { log.Print(err) } defer listener.Close() // validate key key, err := parse.MakeKey(connector.Key) if err != nil { log.Print(err) } // watch for stopped connections go func(commandMsgs chan<- models.Message, connector models.Connector, clients map[string]int) { for { time.Sleep(15 * time.Second) for client, _ := range clients { clients[client] -= 1 if clients[client] < 0 { var m models.Message m.In.ConnectorType = connector.Type m.In.ConnectorID = connector.ID m.In.Tags = connector.Tags m.In.Process = false m.Out.Text = "Jane Alert" m.Out.Detail = "Client Disconnect from " + client m.Out.Status = "FAIL" commandMsgs <- m if connector.Debug { log.Print("Disconnect: ", client) } delete(clients, client) } } } }(commandMsgs, connector, clients) for { // respond to connections conn, err := listener.Accept() if err != nil { log.Print(err) } if connector.Debug { log.Print("New Client Connection by ", conn.RemoteAddr()) } // thread out process go func(commandMsgs chan<- models.Message, connector models.Connector, conn net.Conn, key []byte, clients map[string]int) { defer conn.Close() // establish client counter client := conn.RemoteAddr().String() clients[client] = 3 var m models.Message m.In.ConnectorType = connector.Type m.In.ConnectorID = connector.ID m.In.Tags = connector.Tags m.In.Process = false m.Out.Text = "Jane Alert" m.Out.Detail = "Client Connect from " + client m.Out.Status = "SUCCESS" commandMsgs <- m // loop for { // read in messages messageEvent, err := bufio.NewReader(conn).ReadString('\n') if err != nil { if err == io.EOF { clients[client] = 0 break } else { log.Print(err) } } // convert to bytes messageBytes, err := parse.StrBytesToBytes(messageEvent) if err != nil { log.Print(err) } // decrypt message messageDecrypt, err := parse.Decrypt(key, messageBytes) if err != nil { log.Print(err) } // interpret message if string(messageDecrypt) == "ping" { clients[client] += 1 } else if len(messageDecrypt) > 0 && string(messageDecrypt)[0:1] == "{" { // deserialize message var message models.Message err = json.Unmarshal(messageDecrypt, &message) if err != nil { log.Print(err) } // alter message message.In.ConnectorID = "[" + client + "]" + message.In.ConnectorID timestamp := time.Now().Unix() if timestamp > message.In.Timestamp+120 { delay := strconv.FormatInt(timestamp-message.In.Timestamp, 10) message.Out.Text = message.Out.Text + " [Delayed: " + delay + "s]" } if connector.Debug { log.Printf("Message from %s: %+v", client, message) } // send message commandMsgs <- message } else { log.Print("Client Connection illegal key from ", client) clients[client] = 0 break } } }(commandMsgs, connector, conn, key, clients) } return }