func handleMessage(pool *redis.Pool, zmqPUB *zmq.Socket, msg []byte) { var m common.Message //create an empty Message var r common.Receipt //create an empty Receipt if err := json.Unmarshal(msg, &m); err != nil { //unpack the message into m, check for an error fmt.Println(err) } //end if //setup the receipt we send back to the sender letting them know that r.MessageID = m.MessageID //it has this messageID r.Status = common.RECEIPT_SENDING_STATUS //the status is sending r.OriginDeviceID = "tracker" //it is being reported by the tracker accountIDsToDeviceID := common.TranslateAccountIDtoDeviceID(m.AccountIDs, pool) //translate the accountIDs to the deviceIDs returns a map[string][]string conn := pool.Get() //get a new connection from the pool defer conn.Close() //save the message in the database, so we dont lose it if _, err := conn.Do("SET", "ASMS::pending::messageID:"+m.MessageID+"::message:", msg); err != nil { fmt.Println(err) } //format the reciept into JSON ReceiptJSON, err := json.Marshal(r) if err != nil { fmt.Println(err) } clientsServer, err := redis.String(conn.Do("GET", "ASMS::deviceID:"+m.OriginDeviceID+"::serverID:")) if err != nil { fmt.Println(err) } if err := zmqPUB.SendPart([]byte(clientsServer), true); err != nil { //send to the client fmt.Println(err) } //identify the type of message being sent if err := zmqPUB.SendPart([]byte("Receipt"), true); err != nil { fmt.Println(err) } //end if if err := zmqPUB.SendPart(ReceiptJSON, false); err != nil { fmt.Println(err) } for _, accountID := range accountIDsToDeviceID { //accountID level for _, deviceID := range accountID { //each device associated with the account ID deviceCurrentServer, err := redis.String(conn.Do("GET", "ASMS::connection::deviceID:"+deviceID+"::server:")) //get the current server that the device is on if err != nil { fmt.Println(err) } //end if m.DestinationDeviceID = deviceID //set the destination device id in the message to this deviceID MessageJSON, err := json.Marshal(m) if err != nil { fmt.Println(err) } //set the message as pending, always assume that it never went through if _, err := conn.Do("LPUSH", "ASMS::pending::messageID:"+m.MessageID+"::deviceID:", deviceID); err != nil { fmt.Println(err) } if _, err := conn.Do("LPUSH", "ASMS::pending::deviceID:"+deviceID+"::messageID:", m.MessageID); err != nil { fmt.Println(err) } //send the serverDesination through as the first part if err := zmqPUB.SendPart([]byte(deviceCurrentServer), true); err != nil { fmt.Println(err) } //identify the type of message being sent if err := zmqPUB.SendPart([]byte("Message"), true); err != nil { fmt.Println(err) } //end if //send the message as JSON through if err := zmqPUB.SendPart(MessageJSON, false); err != nil { //second part of the multipart message, this contains the message and all relevant information. fmt.Println(err) } } //end for deviceID } //end for accountID } //end handleMessage
//when the server needs to handle a Receipt func handleReceipt(pool *redis.Pool, zmqPUB *zmq.Socket, rcpt []byte) { var r common.Receipt //create an empty Receipt if err := json.Unmarshal(rcpt, &r); err != nil { //check for an error fmt.Println(err) } //end if accountIDsToDeviceID := common.TranslateAccountIDtoDeviceID(r.AccountIDs, pool) //translate the accountIDs to the deviceIDs returns a map[string][]string conn := pool.Get() //get a new connection from the pool defer conn.Close() switch r.Status { case common.RECEIPT_DELIVERED_STATUS: for _, accountID := range accountIDsToDeviceID { //accounID level for _, deviceID := range accountID { //each device associated with the account ID if deviceID != r.OriginDeviceID { //if the deviceID matches dont send it back deviceCurrentServer, err := redis.String(conn.Do("GET", "ASMS::connection::deviceID:"+deviceID+"::server:")) if err != nil { fmt.Println(err) } //end if r.DestinationDeviceID = deviceID receiptJSON, err := json.Marshal(r) //format the Receipt to JSON if err != nil { fmt.Println(err) } //end if if err := zmqPUB.SendPart([]byte(deviceCurrentServer), true); err != nil { fmt.Println(err) } //end if //identify the type of message being sent if err := zmqPUB.SendPart([]byte("Receipt"), true); err != nil { fmt.Println(err) } //end if //third part of the multipart message, this contains the message and all relevant information. if err := zmqPUB.SendPart(receiptJSON, false); err != nil { fmt.Println(err) } //end if } //end if } //end for deviceID } //end for accountID case common.RECEIPT_READ_STATUS: //remove the messageID from the list in the deviceID ASMS::pending::deviceID:<deviceID>::messageID: <messageID> if _, err := conn.Do("LREM", "ASMS::pending::deviceID:"+r.OriginDeviceID+"::messageID:", 0, r.MessageID); err != nil { fmt.Println(err) } //remove the deviceID from the list in the messageID ASMS::pending::messageID:<messageID>::deviceID: <deviceID> if _, err := conn.Do("LREM", "ASMS::pending::messageID:"+r.MessageID+"::deviceID:", 0, r.OriginDeviceID); err != nil { fmt.Println(err) } //get the list length listLength, err := redis.Int(conn.Do("LLEN", "ASMS::pending::messageID:"+r.MessageID+"::deviceID:")) if err != nil { fmt.Println(err) } if listLength == 0 { // if the length of ASMS::pending::messageID:<messageID>::deviceID: is 0 if _, err := conn.Do("DEL", "ASMS::pending::messageID:"+r.MessageID+"::message:"); err != nil { // then remove ASMS::pending::messageID:<messageID>::message: <message> fmt.Println(err) } //end if } //end if // if the reciept is NOT silent then, 3 is silent!!! if r.Option != 3 { // send read reciept to all people in conversation except the sender. for _, accountID := range accountIDsToDeviceID { //accounID level for _, deviceID := range accountID { //each device associated with the account ID if deviceID != r.OriginDeviceID { //if the deviceID matches dont send it back deviceCurrentServer, err := redis.String(conn.Do("GET", "ASMS::connection::deviceID:"+deviceID+"::server:")) if err != nil { fmt.Println(err) } //end if r.DestinationDeviceID = deviceID //which one do we want to send it too? receiptJSON, err := json.Marshal(r) //format the Receipt to JSON if err != nil { fmt.Println(err) } //end if if err := zmqPUB.SendPart([]byte(deviceCurrentServer), true); err != nil { fmt.Println(err) } //end if //identify the type of message being sent if err := zmqPUB.SendPart([]byte("Receipt"), true); err != nil { fmt.Println(err) } //end if //second part of the multipart message, this contains the message and all relevant information. if err := zmqPUB.SendPart(receiptJSON, false); err != nil { fmt.Println(err) } //end if } //end if } //end for deviceID } //end for accountID } // else we are done case common.RECEIPT_ERROR_STATUS: //do nothing? handled on the device? default: //assume its sending } } //end handleReceipt