Example #1
0
func (m *multiplexer) routeMessages(ws *websocket.Conn) {
	stopSignal := make(chan bool, 1)

	// Read messages from backend
	go func(stop chan<- bool) {
		for {
			msgType, msg, err := ws.ReadMessage()
			if err != nil {
				m.shutdown(stop)
				return
			}

			if msgType != websocket.TextMessage {
				continue
			}
			message := common.ParseMessage(string(msg))

			m.frontendMu.RLock()
			frontendChan, ok := m.frontendChans[message.Key]
			if ok {
				frontendChan <- message
			}
			m.frontendMu.RUnlock()

			if !ok && message.Type != common.Close {
				m.sendClose(message.Key)
			}
		}
	}(stopSignal)

	// Write messages to backend
	go func(stop <-chan bool) {
		ticker := time.NewTicker(time.Second * 5)
		defer ticker.Stop()
		for {
			select {
			case message, ok := <-m.messagesToBackend:
				if !ok {
					return
				}
				err := ws.WriteMessage(websocket.TextMessage, []byte(message))
				if err != nil {
					log.WithFields(log.Fields{"error": err, "msg": message}).Error("Could not write message.")
				}

			case <-ticker.C:
				ws.WriteControl(websocket.PingMessage, []byte(""), time.Now().Add(time.Second))

			case <-stop:
				return
			}
		}
	}(stopSignal)
}
Example #2
0
func (m *multiplexer) routeMessages(ws *websocket.Conn) {
	stopSignal := make(chan bool, 1)

	// Read messages from backend
	go func(stop chan<- bool) {
		for {
			_, msg, err := ws.ReadMessage()
			if err != nil {
				m.shutdown(stop)
				return
			}

			message := common.ParseMessage(string(msg))

			m.frontendMu.RLock()
			frontendChan, ok := m.frontendChans[message.Key]
			if ok {
				frontendChan <- message
			}
			m.frontendMu.RUnlock()

			if !ok && message.Type != common.Close {
				log.WithFields(log.Fields{"Message": message}).Warn(
					"Could not find channel for message. Dropping message and sending close to backend.")
				m.sendClose(message.Key)
			}
		}
	}(stopSignal)

	// Write messages to backend
	go func(stop <-chan bool) {
		for {
			select {
			case message, ok := <-m.messagesToBackend:
				if !ok {
					return
				}
				err := ws.WriteMessage(websocket.TextMessage, []byte(message))
				if err != nil {
					log.WithFields(log.Fields{"error": err, "msg": message}).Error("Could not write message.")
				}
			case <-stop:
				return
			}
		}
	}(stopSignal)
}
Example #3
0
func connectToProxyWS(ws *websocket.Conn, handlers map[string]Handler) {
	responders := make(map[string]chan string)
	responseChannel := make(chan common.Message, 10)

	// Write messages to proxy
	go func() {
		for {
			message, ok := <-responseChannel
			if !ok {
				return
			}
			data := common.FormatMessage(message.Key, message.Type, message.Body)
			ws.WriteMessage(1, []byte(data))
		}
	}()

	// Read and route messages from proxy
	for {
		_, msg, err := ws.ReadMessage()
		if err != nil {
			log.WithFields(log.Fields{"error": err}).Error("Received error reading from socket. Exiting.")
			close(responseChannel)
			return
		}

		message := common.ParseMessage(string(msg))
		switch message.Type {
		case common.Connect:
			requestUrl, err := url.Parse(message.Body)
			if err != nil {
				continue
			}

			handler, ok := getHandler(requestUrl.Path, handlers)
			if ok {
				msgChan := make(chan string, 10)
				responders[message.Key] = msgChan
				go handler.Handle(message.Key, message.Body, msgChan, responseChannel)
			} else {
				log.WithFields(log.Fields{"path": requestUrl.Path}).Warn("Could not find appropriate message handler for supplied path.")
				responseChannel <- common.Message{
					Key:  message.Key,
					Type: common.Close,
					Body: ""}
			}
		case common.Body:
			if msgChan, ok := responders[message.Key]; ok {
				msgChan <- message.Body
			} else {
				log.WithFields(log.Fields{"key": message.Key}).Warn("Could not find responder for specified key.")
				responseChannel <- common.Message{
					Key:  message.Key,
					Type: common.Close,
				}
			}
		case common.Close:
			closeHandler(responders, message.Key)
		default:
			log.WithFields(log.Fields{"messageType": message.Type}).Warn("Unrecognized message type. Closing connection.")
			closeHandler(responders, message.Key)
			SignalHandlerClosed(message.Key, responseChannel)
			continue
		}
	}
}