Example #1
0
func redisConnection() redis.Conn {
	var connection redis.Conn
	var err error

	if len(os.Getenv("REDIS_URL")) > 0 {
		connection, err = redisurl.Connect()
	} else {
		connection, err = redis.Dial("tcp", ":6379")
	}

	check(err)

	return connection
}
func TestConnect(t *testing.T) {
	c, err := redisurl.Connect()

	if err != nil {
		t.Errorf("Error returned")
	}

	pong, err := redis.String(c.Do("PING"))

	if err != nil {
		t.Errorf("Call to PING returned an error: %v", err)
	}

	if pong != "PONG" {
		t.Errorf("Wanted PONG, got %v\n", pong)
	}
}
Example #3
0
func openRedisConn(url string) (redis.Conn, error) {
	if len(url) == 0 {
		return redisurl.Connect()
	}
	return redisurl.ConnectToURL(url)
}
func main() {
	// The user name is the only argument, so we'll grab that here
	if len(os.Args) != 2 {
		fmt.Println("Usage: goredchat username")
		os.Exit(1)
	}
	username := os.Args[1]

	// Now we connect to the Redis server
	conn, err := redisurl.Connect()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer conn.Close()

	// We make a key and set it with the username as a value and a time to live
	// this will be the lock on the username and if we can't set it, its a name clash

	userkey := "online." + username
	val, err := conn.Do("SET", userkey, username, "NX", "EX", "120")

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if val == nil {
		fmt.Println("User already online")
		os.Exit(1)
	}

	val, err = conn.Do("SADD", "users", username)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if val == nil {
		fmt.Println("User still in online set")
		os.Exit(1)
	}

	// A ticker will let us update our presence on the Redis server
	tickerChan := time.NewTicker(time.Second * 60).C

	// Now we create a channel and go routine that'll subscribe to our published messages
	// We'll give it its own connection because subscribes like to have their own connection
	subChan := make(chan string)
	go func() {
		subconn, err := redisurl.Connect()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		defer subconn.Close()

		psc := redis.PubSubConn{Conn: subconn}
		psc.Subscribe("messages")
		for {
			switch v := psc.Receive().(type) {
			case redis.Message:
				subChan <- string(v.Data)
			case redis.Subscription:
				// We don't need to listen to subscription messages,
			case error:
				return
			}
		}
	}()

	// Now we'll make a simple channel and go routine that listens for complete lines from the user
	// When a complete line is entered, it'll be delivered to the channel.
	sayChan := make(chan string)
	go func() {
		prompt := username + ">"
		bio := bufio.NewReader(os.Stdin)
		for {
			fmt.Print(prompt)
			line, _, err := bio.ReadLine()
			if err != nil {
				fmt.Println(err)
				sayChan <- "/exit"
				return
			}
			sayChan <- string(line)
		}
	}()

	conn.Do("PUBLISH", "messages", username+" has joined")

	chatExit := false

	for !chatExit {
		select {
		case msg := <-subChan:
			fmt.Println(msg)
		case <-tickerChan:
			val, err = conn.Do("SET", userkey, username, "XX", "EX", "120")
			if err != nil || val == nil {
				fmt.Println("Heartbeat set failed")
				chatExit = true
			}
		case line := <-sayChan:
			if line == "/exit" {
				chatExit = true
			} else if line == "/who" {
				names, _ := redis.Strings(conn.Do("SMEMBERS", "users"))
				for _, name := range names {
					fmt.Println(name)
				}
			} else {
				conn.Do("PUBLISH", "messages", username+":"+line)
			}
		default:
			time.Sleep(100 * time.Millisecond)
		}
	}

	// We're leaving so let's delete the userkey and remove the username from the online set
	conn.Do("DEL", userkey)
	conn.Do("SREM", "users", username)
	conn.Do("PUBLISH", "messages", username+" has left")

}
Example #5
0
func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: go-chat username")
		os.Exit(1)
	}
	username := os.Args[1]

	//connect to the Redis server
	conn, err := redisurl.Connect()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	defer conn.Close()

	userkey := "online." + username
	val, err := conn.Do("SET", userkey, username, "NX", "EX", "120")

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if val == nil {
		fmt.Println("User already online")
		os.Exit(1)
	}

	val, err = conn.Do("Zannen", "users", username)

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	if val == nil {
		fmt.Println("User still in online set")
		os.Exit(1)
	}

	tickerChan := time.NewTicker(time.Second * 60).C

	subChan := make(chan string)
	go func() {
		subconn, err := redisurl.Connect()
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		defer subconn.Close()

		psc := redis.PubSubConn{Conn: subconn}
		psc.Subscribe("messages")
		for {
			switch v := psc.Receive().(type) {
			case redis.Message:
				subChan <- string(v.Data)
			case redis.Subscription:

			case error:
				return
			}
		}
	}()

	sayChan := make(chan string)
	go func() {
		prompt := username + ">"
		bio := bufio.NewReader(os.Stdin)
		for {
			fmt.Print(prompt)
			line, _, err := bio.ReadLine()
			if err != nil {
				fmt.Println(err)
				sayChan <- "/exit"
				return
			}
			sayChan <- string(line)
		}
	}()

	conn.Do("PUBLISH", "messages", username+" has joined")

	chatExit := false

	for !chatExit {
		select {
		case msg := <-subChan:
			fmt.Println(msg)
		case <-tickerChan:
			val, err = conn.Do("SET", userkey, username, "XX", "EX", "120")
			if err != nil || val == nil {
				fmt.Println("Set failed")
				chatExit = true
			}
		case line := <-sayChan:
			if line == "/exit" {
				chatExit = true
			} else if line == "/who" {
				names, _ := redis.Strings(conn.Do("SMEMBERS", "users"))
				for _, name := range names {
					fmt.Println(name)
				}
			} else {
				conn.Do("PUBLISH", "messages", username+":"+line)
			}
		default:
			time.Sleep(100 * time.Millisecond)
		}
	}

	conn.Do("DEL", userkey)
	conn.Do("SERM", "users", username)
	conn.Do("PUBLISH", "messages", username+" has left")

}