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)) }
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 } } }