Example #1
0
// Read responses from the tunnel and fulfill pending requests
func wsReader(rs *remoteServer, ws *websocket.Conn, wsTimeout time.Duration, ch chan int) {
	var err error
	log_token := cutToken(rs.token)
	// continue reading until we get an error
	for {
		ws.SetReadDeadline(time.Time{}) // no timeout, there's the ping-pong for that
		// read a message from the tunnel
		var t int
		var r io.Reader
		t, r, err = ws.NextReader()
		if err != nil {
			break
		}
		if t != websocket.BinaryMessage {
			err = fmt.Errorf("non-binary message received, type=%d", t)
			break
		}
		// give the sender a fixed time to get us the data
		ws.SetReadDeadline(time.Now().Add(wsTimeout))
		// get request id
		var id int16
		_, err = fmt.Fscanf(io.LimitReader(r, 4), "%04x", &id)
		if err != nil {
			break
		}
		// read request itself, the size is limited by the SetReadLimit on the websocket
		var buf []byte
		buf, err = ioutil.ReadAll(r)
		if err != nil {
			break
		}
		rs.log.Info("WS   RCV", "id", id, "ws", wsp(ws), "len", len(buf))
		// try to match request
		rs.requestSetMutex.Lock()
		req := rs.requestSet[id]
		rs.lastActivity = time.Now()
		rs.requestSetMutex.Unlock()
		// let's see...
		if req != nil {
			rb := responseBuffer{response: bytes.NewBuffer(buf)}
			// try to enqueue response
			select {
			case req.replyChan <- rb:
				// great!
			default:
				rs.log.Info("WS   RCV can't enqueue response", "id", id, "ws", wsp(ws))
			}
		} else {
			rs.log.Info("%s #%d: WS   RCV orphan response", "id", id, "ws", wsp(ws))
		}
	}
	// print error message
	if err != nil {
		rs.log.Info("WS   closing", "token", log_token, "err", err.Error(), "ws", wsp(ws))
	}
	// close up shop
	ch <- 0 // notify sender
	time.Sleep(2 * time.Second)
	ws.Close()
}
Example #2
0
/**
Listen for Pods. We're only interested in MODIFIED and DELETED events.
*/
func listen(wsConn *websocket.Conn, wsErrors chan string) {
	log.Println("Listening for pods")

	for {
		_, r, err := wsConn.NextReader()

		if err != nil {
			log.Printf("Error getting reader: %v", err)
			wsErrors <- "Error"
			return
		}

		dec := json.NewDecoder(r)
		var objmap map[string]*json.RawMessage
		dec.Decode(&objmap)

		var actionType string
		json.Unmarshal(*objmap["type"], &actionType)

		var pod api.Pod
		err = json.Unmarshal(*objmap["object"], &pod)

		switch actionType {
		case "MODIFIED":
			register(pod)
		case "DELETED":
			deletePod(pod)
		}
	}
}
Example #3
0
// Listen for Services.
func svcListener(wsConn *websocket.Conn, wsErrors chan string) {
	log.Println("Listening for services")

	for {
		_, r, err := wsConn.NextReader()

		if err != nil {
			log.Printf("Error getting reader: %v", err)
			wsErrors <- "Error"
			return
		}

		dec := json.NewDecoder(r)

		var objmap map[string]*json.RawMessage
		dec.Decode(&objmap)

		// debug purpose
		// b,_ := json.Marshal(objmap)
		// log.Printf("%s", b)

		var actionType string
		json.Unmarshal(*objmap["type"], &actionType)

		var svc api.Service
		err = json.Unmarshal(*objmap["object"], &svc)

		switch actionType {
		case "ADDED":
			registerSvc(svc)
		case "DELETED":
			unregisterSvc(svc)
		}
	}
}
Example #4
0
func readLoop(c *websocket.Conn) {
	for {
		if _, _, err := c.NextReader(); err != nil {
			c.Close()
			break
		}
	}
}
Example #5
0
func (ws *Websocket) Reader(c *goWs.Conn, closed chan<- bool) {
	defer c.Close()
	for {
		messageType, _, err := c.NextReader()
		if err != nil || messageType == goWs.CloseMessage {
			break
		}
	}
	closed <- true
}
Example #6
0
func keepWsAlive(ws *websocket.Conn) {
	// We repeatedly read from the websocket connections and discard
	// the reader in order to process the underlying ping/pong messages
	// of the websocket connection
	for {
		_, _, err := ws.NextReader()
		if err != nil {
			ws.Close()
			break
		}
	}
}
func ws_null_reader(conn *websocket.Conn, info_ptr *WsInfo) {

	// Apparently reading WebSocket messages from clients is mandatory.
	// This function also closes connections if needed.

	for {
		if _, _, err := conn.NextReader(); err != nil {
			remove_from_ws_client_list(info_ptr)
			conn.Close()
			return
		}
	}
}
func streamWebsocketIOFromContainerizer(ws *websocket.Conn, pidChannel chan<- string, processIO garden.ProcessIO) (int, error) {
	defer close(pidChannel)

	defer func() {
		ws.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))

		go func() {
			for {
				_, _, err := ws.NextReader()
				if err != nil {
					ws.Close()
					break
				}
			}
		}()

	}()

	receiveStream := ProcessStreamEvent{}
	for {
		err := websocket.ReadJSON(ws, &receiveStream)
		if err != nil {
			return -1, err
		}

		if receiveStream.MessageType == "pid" {
			pidChannel <- receiveStream.Data
		}

		if receiveStream.MessageType == "stdout" && processIO.Stdout != nil {
			io.WriteString(processIO.Stdout, receiveStream.Data)
		}
		if receiveStream.MessageType == "stderr" && processIO.Stderr != nil {
			io.WriteString(processIO.Stderr, receiveStream.Data)
		}

		if receiveStream.MessageType == "error" {
			return -1, errors.New(receiveStream.Data)
		}
		if receiveStream.MessageType == "close" {
			exitCode, err := strconv.Atoi(receiveStream.Data)
			if err != nil {
				return -1, err
			}
			return exitCode, nil
		}
	}
}
Example #9
0
func (this *Server) NewConnection(conn *websocket.Conn) (string, error) {
	_, reader, err := conn.NextReader()
	if err != nil {
		glog.Errorf("Error establishing new connection: %s", err.Error())
	}
	user, err := message.GetUser(reader)
	if err != nil {
		return "", err
	}

	glog.Infof("Register conenction with uid: %s", user.Uid)
	this.Users[user.Uid] = NewClient(conn, user)
	this.Users[user.Uid].Send(user, message.MSG_USER_DATA)

	return user.Uid, nil
}
Example #10
0
func WebsocketRecvStream(w io.WriteCloser, conn *websocket.Conn) chan bool {
	ch := make(chan bool)

	go func(w io.WriteCloser, conn *websocket.Conn) {
		for {
			mt, r, err := conn.NextReader()
			if mt == websocket.CloseMessage {
				Debugf("Got close message for reader")
				break
			}

			if mt == websocket.TextMessage {
				Debugf("got message barrier")
				break
			}

			if err != nil {
				Debugf("Got error getting next reader %s, %s", err, w)
				break
			}

			buf, err := ioutil.ReadAll(r)
			if err != nil {
				Debugf("Got error writing to writer %s", err)
				break
			}

			if w == nil {
				continue
			}

			i, err := w.Write(buf)
			if i != len(buf) {
				Debugf("Didn't write all of buf")
				break
			}
			if err != nil {
				Debugf("Error writing buf %s", err)
				break
			}
		}
		ch <- true
	}(w, conn)

	return ch
}
Example #11
0
func wsReader(conn *websocket.Conn, m chan<- message, e chan<- error) {
	for {
		t, r, err := conn.NextReader()
		if err != nil {
			e <- io.EOF
			return
		}

		msg, err := ioutil.ReadAll(r)
		if err != nil {
			e <- err
			return
		}

		m <- message{ws.MsgType(t), msg}
	}
}
Example #12
0
func (sc *ServerConnection) read(ws *websocket.Conn) {

	// log.Println("Response", resp)

	status := new(ServerUpdate)
	status.ConnID = sc.ConnID

	for {

		select {
		case <-sc.quit:
			log.Println("server reader got quit message")
			sc.quit <- true
			return

		default:

			ws.SetReadDeadline(time.Now().Add(time.Second * 3))
			sc.statusMsg("Ok")
			op, r, err := ws.NextReader()
			if err != nil {
				status := fmt.Sprintf("Error reading from server: %s", err)
				sc.statusErrorMsg(status)
				log.Println(status)
				return
			}
			msg, err := ioutil.ReadAll(r)

			// log.Println("op", op, "msg", string(msg), "err", err)

			if op == websocket.TextMessage {
				err = json.Unmarshal(msg, &status)
				if err != nil {
					log.Printf("Unmarshall err from '%s': '%s', data: '%s'\n", sc.IP.String(), err, msg)
				}
				// log.Printf("Got status: %#v\n", status)
				sc.updateChan <- status
			} else {
				log.Println("op", op, "msg", string(msg), "err", err)
			}

			// os.Exit(0)
		}
	}
}
Example #13
0
func processRotondePackets(conn *websocket.Conn, inChan, outChan chan interface{}) {
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()

		for {
			select {
			case dispatcherPacket := <-inChan:
				jsonPacket, err := rotonde.ToJSON(dispatcherPacket)
				if err != nil {
					log.Warning(err)
				}
				if err := conn.WriteMessage(websocket.TextMessage, jsonPacket); err != nil {
					log.Fatal(err)
					return
				}
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()

		for {
			messageType, reader, err := conn.NextReader()
			if err != nil {
				log.Fatal(err)
				return
			}
			if messageType == websocket.TextMessage {
				dispatcherPacket, err := rotonde.FromJSON(reader)
				if err != nil {
					log.Warning(err)
				}
				outChan <- dispatcherPacket
			}
		}
	}()

	log.Info("Treating messages")
	wg.Wait()
}
Example #14
0
// reader is the guts of this package. It takes the stdin and stdout pipes
// of the cmd we created in ServeWS and pipes them between the client and server
// over websockets.
func reader(conn *websocket.Conn, stdout io.ReadCloser, stdin io.WriteCloser) {
	// Setup our connection's websocket ping/pong handlers from our const values.
	conn.SetReadLimit(maxMessageSize)
	conn.SetReadDeadline(time.Now().Add(pongWait))
	conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(pongWait)); return nil })
	tickerChan := make(chan bool)
	defer close(tickerChan) // make sure to close the ticker when we are done.
	go ticker(conn, tickerChan)

	for {
		msgType, r, err := conn.NextReader()
		if err != nil {
			if msgType == -1 {
				return // we got a disconnect from the client. We are good to close.
			}
			conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, ""), time.Time{})
			return
		}

		w, err := conn.NextWriter(msgType)
		if err != nil {
			conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, ""), time.Time{})
			return
		}

		if _, err := io.Copy(stdin, r); err != nil {
			conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, ""), time.Time{})
			return
		}

		go func() {
			if _, err := io.Copy(w, stdout); err != nil {
				conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, ""), time.Time{})
				return
			}
			if err := w.Close(); err != nil {
				conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseGoingAway, ""), time.Time{})
				return
			}
		}()
	}
}
Example #15
0
func WSHandler(c *websocket.Conn) {
	closed := false
	ret := websocket.CloseError{
		Code: websocket.CloseNormalClosure,
	}
	const writeWait = 10 * time.Second

	defer func() {
		log.Infof("Close websocket [%s]", ret.Error())
		c.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(ret.Code, ret.Text), time.Now().Add(writeWait))
		c.Close()
	}()

	go func() {
		for {
			_, r, err := c.NextReader()
			if err != nil {
				break
			}
			io.Copy(ioutil.Discard, r)
		}
		log.Infof("Pipe closed")

		closed = true
	}()

	for !closed {
		signal := M{
			"pm2.5": atomic.LoadInt32(&currentPM25),
			"pm10":  atomic.LoadInt32(&currentPM100),
		}
		if err := c.WriteJSON(signal); err != nil && err != websocket.ErrCloseSent {
			if _, ok := err.(net.Error); !ok {
				log.Warnf("Error writing to client: %s", err.Error())
			}
			closed = true
		}
		time.Sleep(2 * time.Second)
	}
}
Example #16
0
func readMessage(c *websocket.Conn, t *testing.T) Message {
	op, r, err := c.NextReader()

	if op != websocket.TextMessage {
		t.Error("expecting a text message")
	}

	if err != nil {
		t.Error("cannot create reader")
	}

	str, err := ioutil.ReadAll(r)
	if err != nil {
		t.Error("websocket read error")
	}

	msg := Message{}
	if err := json.Unmarshal(str, &msg); err != nil {
		t.Error("cannot parse websocket response")
	}

	return msg
}
Example #17
0
File: user.go Project: zvin/vandal
func (user *User) Receiver(location *Location, ws *websocket.Conn) {
	// receives and decodes messages from users
	go func() {
		ws.SetReadLimit(MAX_MESSAGE_SIZE)
		ws.SetReadDeadline(time.Now().Add(PONG_WAIT))
		ws.SetPongHandler(func(string) error {
			ws.SetReadDeadline(time.Now().Add(PONG_WAIT))
			return nil
		})
		for {
			op, r, err := ws.NextReader()
			if err != nil {
				user.Kick(err.Error())
				return
			}
			switch op {
			case websocket.BinaryMessage:
				data, err := ioutil.ReadAll(r)
				if err != nil {
					user.Kick(err.Error())
					return
				}
				var event []interface{}
				err = codec.NewDecoderBytes(data, &msgpackHandle).Decode(&event)
				if err != nil {
					user.Kick(err.Error())
					return
				}
				location.Message <- &UserAndEvent{user, &event}
			default:
				user.Kick(fmt.Sprintf("bad message type: %v", op))
				return
			}
		}
	}()
}
func addSlowWSSink(receivedChan chan []byte, errChan chan error, timeout time.Duration, url string) {
	var ws *websocket.Conn
	tryToConnect := func() error {
		var err error
		ws, _, err = websocket.DefaultDialer.Dial(url, http.Header{})
		return err
	}
	Eventually(tryToConnect, 5).ShouldNot(HaveOccurred())

	go func() {
		time.Sleep(timeout)
		_, reader, err := ws.NextReader()
		if err != nil {
			errChan <- err
			return
		}
		received, err := ioutil.ReadAll(reader)
		if err != nil {
			errChan <- err
			return
		}
		receivedChan <- received
	}()
}
Example #19
0
func startWebsocketConnection(conn *websocket.Conn, d *Dispatcher) {
	c := NewConnection()
	d.AddConnection(c)
	defer c.Close()

	errChan := make(chan error, 1)
	defer close(errChan)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()

		for {
			select {
			case dispatcherPacket := <-c.InChan:
				jsonPacket, err := rotonde.ToJSON(dispatcherPacket)
				if err != nil {
					log.Warning(err)
				}
				if err := conn.WriteMessage(websocket.TextMessage, jsonPacket); err != nil {
					log.Warning(err)
					return
				}
			case <-errChan:
				log.Warning("Got error from errChan")
				return
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()

		for {
			messageType, reader, err := conn.NextReader()
			if err != nil {
				log.Warning(err)
				errChan <- err
				return
			}
			if messageType == websocket.TextMessage {
				dispatcherPacket, err := rotonde.FromJSON(reader)
				if err != nil {
					log.Warning(err)
				}
				c.OutChan <- dispatcherPacket
			}
		}
	}()

	log.Info("Treating messages")
	wg.Wait()
	select {
	case <-errChan:
		log.Warning("errChan was not empty")
	default:
		log.Warning("errChan was empty")
	}
	log.Info("Websocket connection end")
}
Example #20
0
// WebsocketMirror allows mirroring a reader to a websocket and taking the
// result and writing it to a writer. This function allows for multiple
// mirrorings and correctly negotiates stream endings. However, it means any
// websocket.Conns passed to it are live when it returns, and must be closed
// explicitly.
func WebsocketMirror(conn *websocket.Conn, w io.WriteCloser, r io.ReadCloser) (chan bool, chan bool) {
	readDone := make(chan bool, 1)
	writeDone := make(chan bool, 1)
	go func(conn *websocket.Conn, w io.WriteCloser) {
		for {
			mt, r, err := conn.NextReader()
			if err != nil {
				Debugf("Got error getting next reader %s, %s", err, w)
				break
			}

			if mt == websocket.CloseMessage {
				Debugf("Got close message for reader")
				break
			}

			if mt == websocket.TextMessage {
				Debugf("Got message barrier, resetting stream")
				break
			}

			buf, err := ioutil.ReadAll(r)
			if err != nil {
				Debugf("Got error writing to writer %s", err)
				break
			}
			i, err := w.Write(buf)
			if i != len(buf) {
				Debugf("Didn't write all of buf")
				break
			}
			if err != nil {
				Debugf("Error writing buf %s", err)
				break
			}
		}
		writeDone <- true
		w.Close()
	}(conn, w)

	go func(conn *websocket.Conn, r io.ReadCloser) {
		in := ReaderToChannel(r)
		for {
			buf, ok := <-in
			if !ok {
				readDone <- true
				r.Close()
				Debugf("sending write barrier")
				conn.WriteMessage(websocket.TextMessage, []byte{})
				return
			}
			w, err := conn.NextWriter(websocket.BinaryMessage)
			if err != nil {
				Debugf("Got error getting next writer %s", err)
				break
			}

			_, err = w.Write(buf)
			w.Close()
			if err != nil {
				Debugf("Got err writing %s", err)
				break
			}
		}
		closeMsg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
		conn.WriteMessage(websocket.CloseMessage, closeMsg)
		readDone <- true
		r.Close()
	}(conn, r)

	return readDone, writeDone
}
Example #21
0
// WebsocketMirror allows mirroring a reader to a websocket and taking the
// result and writing it to a writer.
func WebsocketMirror(conn *websocket.Conn, w io.WriteCloser, r io.Reader) chan bool {
	done := make(chan bool, 2)
	go func(conn *websocket.Conn, w io.WriteCloser) {
		for {
			mt, r, err := conn.NextReader()
			if mt == websocket.CloseMessage {
				Debugf("got close message for reader")
				break
			}

			if err != nil {
				Debugf("got error getting next reader %s, %s", err, w)
				break
			}
			buf, err := ioutil.ReadAll(r)
			if err != nil {
				Debugf("got error writing to writer %s", err)
				break
			}
			i, err := w.Write(buf)
			if i != len(buf) {
				Debugf("didn't write all of buf")
				break
			}
			if err != nil {
				Debugf("error writing buf %s", err)
				break
			}
		}
		done <- true
		w.Close()
	}(conn, w)

	go func(conn *websocket.Conn, r io.Reader) {
		in := ReaderToChannel(r)
		for {
			buf, ok := <-in
			if !ok {
				done <- true
				conn.WriteMessage(websocket.CloseMessage, []byte{})
				conn.Close()
				return
			}
			w, err := conn.NextWriter(websocket.BinaryMessage)
			if err != nil {
				Debugf("got error getting next writer %s", err)
				break
			}

			_, err = w.Write(buf)
			w.Close()
			if err != nil {
				Debugf("got err writing %s", err)
				break
			}
		}
		closeMsg := websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")
		conn.WriteMessage(websocket.CloseMessage, closeMsg)
		done <- true
	}(conn, r)

	return done
}
Example #22
0
// Stream will init a new pubsub.KafkaPublisher and pubsub.KafkaSubscriber
// then upgrade the current request to a websocket connection. Any messages
// consumed from Kafka will be published to the web socket and vice versa.
func (s *StreamService) Stream(w http.ResponseWriter, r *http.Request) {
	cfg := *s.cfg
	cfg.Topic = topicName(web.GetInt64Var(r, "stream_id"))
	server.LogWithFields(r).WithField("topic", cfg.Topic).Info("new stream req")

	sub, err := pubsub.NewKafkaSubscriber(&cfg, zeroOffset, discardOffset)
	if err != nil {
		server.LogWithFields(r).WithField("error", err).Error("unable to create sub")
		http.Error(w, "unable to create subscriber: "+err.Error(), http.StatusBadRequest)
		return
	}
	defer func() {
		if err := sub.Stop(); err != nil {
			server.LogWithFields(r).WithField("error", err).Error("unable to stop sub")
		}
	}()

	var pub *pubsub.KafkaPublisher
	pub, err = pubsub.NewKafkaPublisher(&cfg)
	if err != nil {
		server.LogWithFields(r).WithField("error", err).Error("unable to create pub")
		http.Error(w, "unable to create publisher: "+err.Error(), http.StatusBadRequest)
		return
	}
	defer func() {
		if err := pub.Stop(); err != nil {
			server.LogWithFields(r).WithField("error", err).Error("unable to stop pub")
		}
	}()
	var ws *websocket.Conn
	ws, err = upgrader.Upgrade(w, r, nil)
	if err != nil {
		server.LogWithFields(r).WithField("error", err).Error("unable to create websocket")
		http.Error(w, "unable to create websocket: "+err.Error(), http.StatusBadRequest)
		return
	}
	defer func() {
		if err := ws.Close(); err != nil {
			server.LogWithFields(r).WithField("error", err).Error("unable to close ws")
		}
	}()

	// start consumer, emit to ws
	noopTicker := time.NewTicker(time.Second * 5)
	subscriberDone := make(chan bool, 1)
	stopSubscriber := make(chan bool, 1)
	go func() {
		defer func() { subscriberDone <- true }()
		var (
			payload []byte
			msgs    = sub.Start()
		)
		for {
			select {
			case msg := <-msgs:
				payload = msg.Message()
				err = ws.SetWriteDeadline(time.Now().Add(time.Second * 30))
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to write deadline")
				}
				err = ws.WriteMessage(websocket.TextMessage, payload)
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to write ws message")
				}
				err = msg.Done()
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to mark gizmo message as done")
				}
			case <-noopTicker.C:
				err = ws.SetWriteDeadline(time.Now().Add(time.Second * 30))
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to write deadline")
				}
				if err := ws.WriteMessage(websocket.PingMessage, []byte("ping")); err != nil {
					server.LogWithFields(r).WithField("error", err).Error("error writing ws message")
					return
				}
			case <-stopSubscriber:
				return
			}
		}
	}()

	// start producer, emit to kafka
	producerDone := make(chan bool, 1)
	go func() {
		defer func() {
			producerDone <- true
			stopSubscriber <- true
			server.LogWithFields(r).WithField("topic", cfg.Topic).Info("closing stream req")
		}()
		var (
			messageType int
			payload     []byte
			err         error
			read        io.Reader
		)
		for {
			messageType, read, err = ws.NextReader()
			if err != nil {
				if err != io.EOF {
					server.LogWithFields(r).WithField("error", err).Error("error reading message")
				}
				return
			}

			switch messageType {
			case websocket.TextMessage:
				payload, err = ioutil.ReadAll(read)
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to read payload")
					return
				}
				err = pub.PublishRaw(cfg.Topic, payload)
				if err != nil {
					server.LogWithFields(r).WithField("error", err).Error("unable to publish payload")
					return
				}
			case websocket.PingMessage, websocket.PongMessage, websocket.BinaryMessage:
				server.LogWithFields(r).Info("discarding message type: ", messageType)
			case websocket.CloseMessage:
				server.LogWithFields(r).Info("closing websocket")
				return
			}
		}
	}()

	<-subscriberDone
	<-producerDone
	noopTicker.Stop()
	server.LogWithFields(r).WithField("topic", cfg.Topic).Info("leaving stream req")
}
Example #23
0
func startConnection(conn *websocket.Conn, d *Dispatcher) {
	c := NewConnection()
	d.AddConnection(c)
	defer c.Close()

	errChan := make(chan error)
	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()

		var jsonPacket []byte
		var err error
		var packet rotonde.Packet

		for {
			select {
			case dispatcherPacket := <-c.InChan:
				switch data := dispatcherPacket.(type) {
				case rotonde.Event:
					packet = rotonde.Packet{Type: "event", Payload: data}
				case rotonde.Action:
					packet = rotonde.Packet{Type: "action", Payload: data}
				case rotonde.Definition:
					packet = rotonde.Packet{Type: "def", Payload: data}
				case rotonde.UnDefinition:
					packet = rotonde.Packet{Type: "undef", Payload: data}
				default:
					log.Info("Oops unknown packet: ", dispatcherPacket)
				}

				jsonPacket, err = json.Marshal(packet)
				if err != nil {
					log.Warning(err)
				}

				if err := conn.WriteMessage(websocket.TextMessage, jsonPacket); err != nil {
					log.Warning(err)
					return
				}

			case <-errChan:
				return
			}
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()

		var dispatcherPacket interface{}

		for {
			messageType, reader, err := conn.NextReader()
			if err != nil {
				log.Println(err)
				errChan <- err
				return
			}
			if messageType == websocket.TextMessage {
				packet := rotonde.Packet{}
				decoder := json.NewDecoder(reader)
				if err := decoder.Decode(&packet); err != nil {
					log.Warning(err)
					continue
				}

				switch packet.Type {
				case "event":
					event := rotonde.Event{}
					mapstructure.Decode(packet.Payload, &event)
					dispatcherPacket = event
				case "action":
					action := rotonde.Action{}
					mapstructure.Decode(packet.Payload, &action)
					dispatcherPacket = action
				case "sub":
					subscription := rotonde.Subscription{}
					mapstructure.Decode(packet.Payload, &subscription)
					dispatcherPacket = subscription
				case "unsub":
					unsubscription := rotonde.Unsubscription{}
					mapstructure.Decode(packet.Payload, &unsubscription)
					dispatcherPacket = unsubscription
				case "def":
					definition := rotonde.Definition{}
					mapstructure.Decode(packet.Payload, &definition)
					dispatcherPacket = definition
				case "undef":
					unDefinition := rotonde.UnDefinition{}
					mapstructure.Decode(packet.Payload, &unDefinition)
					dispatcherPacket = unDefinition
				}

				c.OutChan <- dispatcherPacket
			}
		}
	}()

	log.Println("Treating messages")
	wg.Wait()
}