Ejemplo n.º 1
0
func subscribeWebsocket(resp http.ResponseWriter, req *http.Request, topic string, useNewPublisher func(pubsub.Publisher) error) {
	updates, err := pubsub.Subscribe(topic, useNewPublisher)
	if err != nil {
		log.Println("subscribing for updates on", topic, "failed:", err)
		resp.WriteHeader(http.StatusInternalServerError)
		return
	}

	conn, err := upgrader.Upgrade(resp, req, nil)
	if err != nil {
		log.Println(err)
		return
	}

	viewer := &Viewer{
		Conn:          conn,
		ServerAddress: topic,
		Updates:       updates,
	}

	viewer.writeUpdatesUntilClose()

	pubsub.Unsubscribe(updates, topic)

	_ = viewer.Close()
}
func (ms *MasterServerPoller) refreshServers() error {
	// open connection
	conn, err := net.DialTimeout("tcp", ms.Address, 15*time.Second)
	if err != nil {
		return err
	}
	defer conn.Close()

	in := bufio.NewScanner(conn)
	out := bufio.NewWriter(conn)

	// request new list
	_, err = out.WriteString("list\n")
	if err != nil {
		return err
	}

	err = out.Flush()
	if err != nil {
		return err
	}

	updatedList := map[string]extinfo.BasicInfo{}

	// process response
	for in.Scan() {
		msg := in.Text()
		if msg == "\x00" {
			// end of list
			continue
		}

		msg = strings.TrimPrefix(msg, "addserver ")
		msg = strings.TrimSpace(msg)

		addr := strings.Replace(msg, " ", ":", -1)

		// keep old state if possible
		oldState, known := ms.ServerStates[addr]
		updatedList[addr] = oldState

		if !known {
			// subscribe to updates if the server is new
			updates, err := pubsub.Subscribe(addr, func(publisher pubsub.Publisher) error {
				return NewServerPoller(
					publisher,
					func(sp *ServerPoller) { sp.Address = addr },
				)
			})
			if err != nil {
				log.Println("error subscribing to updates on "+addr+":", err)
			}

			ms.Subscriptions[addr] = updates

			go func(updates <-chan pubsub.Update) {
				for upd := range updates {
					ms.ServerUpdates <- upd
				}
			}(updates)
		}
	}

	// unsubscribe from updates about servers not on the list anymore
	for addr := range ms.ServerStates {
		if _, ok := updatedList[addr]; !ok {
			pubsub.Unsubscribe(ms.ServerUpdates, addr)
			delete(ms.Subscriptions, addr)
		}
	}

	ms.ServerStates = updatedList

	return in.Err()
}