Beispiel #1
0
func main() {
	server, err := socketio.NewServer(nil)
	if err != nil {
		log.Fatal(err)
	}
	server.On("connection", func(so socketio.Socket) {
		so.On("subscribe", func(channel string) {
			log.Printf("subscribing to %s\n", channel)
			go subscribe(so, channel)
		})
	})
	http.HandleFunc("/p/", func(w http.ResponseWriter, r *http.Request) {
		red, err := redis.Dial("tcp", ":6379")
		if err != nil {
			log.Println(err)
			return
		}
		path := r.URL.Path
		matches := pathPingRe.FindStringSubmatch(path)
		var token string
		if len(matches) > 1 {
			token = matches[1]
		} else {
			token = "public"
		}
		ip := r.RemoteAddr
		if v, ok := r.Header["X-Forwarded-For"]; ok && len(v) > 0 {
			ip = v[0]
		}
		host := r.Host
		if v, ok := r.Header["X-Real-Host"]; ok && len(v) > 0 {
			host = v[0]
		}
		data, err := json.Marshal(&Record{
			Ip:      ip,
			Time:    time.Now().UTC().Unix(),
			Token:   token,
			Type:    "HTTP",
			Path:    path,
			Headers: r.Header,
			Domain:  host,
		})
		if err != nil {
			log.Println(err)
			return
		}
		red.Do("PUBLISH", token, data)
		red.Do("LPUSH", token, data)
		red.Do("LTRIM", token, 0, 999)
	})
	http.Handle("/socket.io/", server)
	log.Println("Serving at localhost:5007...")
	log.Fatal(http.ListenAndServe(":5007", nil))
}
Beispiel #2
0
func subscribe(so socketio.Socket, channel string) {
	c, err := redis.Dial("tcp", ":6379")
	if err != nil {
		log.Print(err)
		return
	}
	done := make(chan int, 1)
	ret := make(chan string)
	so.On("disconnection", func() {
		done <- 1
	})

	psc := redis.PubSubConn{c}
	psc.Subscribe(channel)
	go func() {
		defer func() {
			psc.Unsubscribe()
		}()
		for {
			select {
			case <-done:
				return
			case val, ok := <-ret:
				if !ok {
					return
				}
				if !emit(so, channel, val) {
					return
				}
			}
		}
	}()
	defer func() {
		psc.Close()
		close(ret)
	}()
	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			log.Printf("%s: message: %s\n", v.Channel, v.Data)
			ret <- string(v.Data)
		case redis.Subscription:
			if v.Count == 0 {
				return
			}
		case error:
			done <- 1
			return
		}
	}
}