Skip to content

Instantly share code, notes, and snippets.

@tristanwietsma
Created April 30, 2013 04:44
Show Gist options
  • Save tristanwietsma/5486625 to your computer and use it in GitHub Desktop.
Save tristanwietsma/5486625 to your computer and use it in GitHub Desktop.
Redis to websocket relay Relays a Redis channel to a websocket, or multiple channels to multiple sockets.
<html>
<head>
<title>Redis Listener</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
var conn;
var msg = $("#msg");
var log = $("#log");
function appendLog(msg) {
var d = log[0]
var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;
msg.appendTo(log)
if (doScroll) {
d.scrollTop = d.scrollHeight - d.clientHeight;
}
}
if (window["WebSocket"]) {
conn = new WebSocket("ws://0.0.0.0:8080/ws");
conn.onclose = function(evt) {
appendLog($("<div><b>Connection closed.</b></div>"))
}
conn.onmessage = function(evt) {
appendLog($("<div/>").text(evt.data))
}
} else {
appendLog($("<div><b>Your browser does not support WebSockets.</b></div>"))
}
});
</script>
<style type="text/css">
html {
overflow: hidden;
}
body {
overflow: hidden;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background: gray;
}
#log {
background: white;
margin: 0;
padding: 0.5em 0.5em 0.5em 0.5em;
position: absolute;
top: 0.5em;
left: 0.5em;
right: 0.5em;
bottom: 3em;
overflow: auto;
}
</style>
</head>
<body>
<div id="log"></div>
</body>
</html>
package main
import (
"fmt"
"log"
"net/http"
"code.google.com/p/go.net/websocket"
"github.com/vmihailenco/redis"
)
type connection struct {
ws *websocket.Conn
}
func SocketHandler(redis_channel string, socket_name string, rc *redis.Client) {
http.Handle("/"+socket_name, websocket.Handler(func(ws *websocket.Conn) {
// set up connection
c := &connection{ws: ws}
h.register <- c
defer func() { h.unregister <- c }()
// redis relay
pubsub, _ := rc.PubSubClient()
defer pubsub.Close()
ch, _ := pubsub.Subscribe(redis_channel)
subscribeMsg := <-ch
fmt.Println(subscribeMsg.Err, subscribeMsg.Name)
for {
msg := <-ch
fmt.Println(msg.Message)
err := websocket.Message.Send(c.ws, msg.Message)
if err != nil {
fmt.Println(err)
break
}
}
}))
}
type hub struct {
connections map[*connection]bool
broadcast chan string
register chan *connection
unregister chan *connection
}
var h = hub{
broadcast: make(chan string),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
}
func (h *hub) run() {
for {
select {
case c := <-h.register:
fmt.Println("Opening new connection.")
h.connections[c] = true
case c := <-h.unregister:
delete(h.connections, c)
fmt.Println("Closing connection.")
}
}
}
func main() {
client := redis.NewTCPClient("localhost:6379", "", -1)
defer client.Close()
go h.run()
SocketHandler("test", "ws", client)
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe:", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment