Ejemplo n.º 1
0
Archivo: command.go Proyecto: elos/gaia
// Expects: the context to hold the authed user
func CommandWebGET(ctx context.Context, ws *websocket.Conn, logger services.Logger, db data.DB) {
	u, ok := user.FromContext(ctx)
	if !ok {
		logger.Print("CommandWebGET Error: failed to retrieve user from context")
		return
	}

	input := make(chan string)
	output := make(chan string)

	session := command.NewSession(
		u, db, input, output,
		func() {
			log.Print("CommandWebGET bail")
			close(output)
		},
	)

	go session.Start()

	go func() {
		for {
			var message string
			err := websocket.Message.Receive(ws, &message)

			if err != nil {
				if err != io.EOF {
					log.Printf("Read fail: %s", err)
				}

				close(output) // should this know about output
				return
			}

			input <- message
		}
	}()

	for o := range output {
		err := websocket.Message.Send(ws, o)

		if err != nil {
			log.Printf("Write fail: %s", err)
			return
		}
	}
}
Ejemplo n.º 2
0
func (mux *webMux) Start(ctx context.Context, db data.DB) {
	timeouts := make(chan data.ID)

Run:
	for {
		select {
		case socket := <-mux.inbound:
			sessionInfo, sessionExists := mux.sessions[socket.User.ID()]

			if sessionExists {
				websocket.Message.Send(socket.Conn, "A user may only have one command session at once")
				if err := socket.Conn.Close(); err != nil {
					log.Printf("Error closing socket: %s", err)
				}
				return
			}

			// otherwise instantiate one

			sessionInput := make(chan string)
			sessionOutput := make(chan string)

			var bail = func() {
				timeouts <- socket.User.ID()
			}

			// We want to forward strings on output channel
			// to the websocket
			go func(out <-chan string, uid data.ID) {
				for o := range out {
					log.Printf("Forwarding: %s", o)
					err := websocket.Message.Send(socket.Conn, o)

					// timeout if error sending message
					if err != nil {
						log.Print("Read off bailing")
						bail()
						return
					}
					log.Print("Forwarded")
				}
			}(sessionOutput, socket.User.ID())

			// Foward input
			go func(in chan<- string) {
				for {
					var incoming string
					err := websocket.Message.Receive(socket.Conn, &incoming)

					if err != nil {
						log.Printf("Error reading from socket: %s", err)
						bail()
						return
					}

					in <- incoming
				}
			}(sessionInput)

			session := command.NewSession(
				socket.User, db, sessionInput, sessionOutput,
				func() {
					timeouts <- socket.User.ID()
				})
			go session.Start()

			sessionInfo = &commandSessionInfo{
				input:   sessionInput,
				session: session,
			}

			mux.sessions[socket.User.ID()] = sessionInfo
		case uid := <-timeouts:
			if session, exists := mux.sessions[uid]; exists {
				close(session.input)
				delete(mux.sessions, uid)
			}
		case <-ctx.Done():
			break Run
		}
	}

	// close all inputs
	for _, sessionInfo := range mux.sessions {
		close(sessionInfo.input)
	}
}