// Asks the message writer to write the error message to its websocket and terminate // This function waits on a message from the closeChan to ensure that func (msgWriter *W) ErrorAndClose(tId uint, uId, errMsg string) { logutil.Log(tId, uId, "Connection Terminated: "+errMsg) closeChan := make(chan bool, 1) sd := &shutdown{closeChan, msgdef.NewServerError(tId, uId, errMsg)} msgWriter.shutdownChan <- sd <-closeChan logutil.Log(tId, uId, "Close Confirmation Received") }
// Writes the contents of sMsg back to ws, returning any errors encountered func writeback(ws *websocket.Conn, sMsg *msgdef.ServerMsg) error { msg := sMsg.Msg bytes, err := json.Marshal(msg) if err != nil { return err } logutil.Log(sMsg.TId, sMsg.UId, fmt.Sprintf("Server Sent: %s", bytes)) _, err = ws.Write(bytes) return err }
// Loops listening for messages to write back to msgWriter's websocket // There are two possible messages to receive // 1: Server message // The contents of the server message is marshalled and written back to the websocket // If an error occurs the error is logged and written back to the websocket // Loop continues // 2: shutdown message // The contents of the shutdown message's server message is marshalled and written back to the websocket // If an error occurs the error is logged and written back to the websocket // shutdown messages closeChan is sent a value, allowing the sender to unblock // Loop terminates func (msgWriter *W) listenAndWriteback() { for { var sMsg *msgdef.ServerMsg var closeChan chan bool select { case sMsg = <-msgWriter.msgChan: case sd := <-msgWriter.shutdownChan: sMsg = sd.errMsg closeChan = sd.closeChan } if err := writeback(msgWriter.ws, sMsg); err != nil { logutil.Log(sMsg.TId, sMsg.UId, err.Error()) } if closeChan != nil { logutil.Log(sMsg.TId, sMsg.UId, "Error message received - Shutting Down") closeChan <- true return } } }
// Unmarshals a websocket message into msgi as JSON. func UnmarshalAndLog(tId uint, uId string, ws *websocket.Conn, msg interface{}) error { var data string if err := websocket.Message.Receive(ws, &data); err != nil { return err } logutil.Log(tId, uId, data) if err := json.Unmarshal([]byte(data), msg); err != nil { return err } return nil }
func processMsg(tId uint, msg *msgdef.CMsgMsg, usr *user.U) func() error { return func() error { if msg.Op != msgdef.CMsgOp { return errors.New("Incorrect op-code for msg: " + string(msg.Op)) } if err := msg.Validate(); err != nil { return err } if idMap.Contains(msg.To) { forUser := idMap.Get(msg.To).(*user.U) safeContent := jsonutil.SanitiseJSON(msg.Content) msgMsg := &msgdef.SMsgMsg{Op: msgdef.SMsgOp, From: usr.Id, Content: safeContent} sMsg := &msgdef.ServerMsg{Msg: msgMsg, TId: tId, UId: usr.Id} forUser.MsgWriter.WriteMsg(sMsg) logutil.Log(tId, usr.Id, fmt.Sprintf("Content: '%s' sent to: '%s'", msg.Content, msg.To)) } else { nuMsg := &msgdef.SMsgMsg{Op: msgdef.SNotUserOp, From: msg.To, Content: fmt.Sprintf("User: %s was not found", msg.To)} sMsg := &msgdef.ServerMsg{Msg: nuMsg, TId: tId, UId: usr.Id} usr.MsgWriter.WriteMsg(sMsg) } return nil } }
// Logs a task involving an old and new location point func locLogL(tId uint, uId, taskDesc string, oMNS, oMEW, nMNS, nMEW float64) { logutil.Log(tId, uId, fmt.Sprintf("%s - oMNS: %f oMEW %f nMNS: %f nMEW %f", taskDesc, oMNS, oMEW, nMNS, nMEW)) }
// Logs a task involving only a single location point func locLog(tId uint, uId, taskDesc string, mNS, mEW float64) { logutil.Log(tId, uId, fmt.Sprintf("%s - mNS: %f mEW: %f", taskDesc, mNS, mEW)) }