Example #1
0
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
Example #2
0
//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