Created
December 4, 2011 14:53
-
-
Save m0nocle/1430375 to your computer and use it in GitHub Desktop.
Go Websocket example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"flag" | |
"log" | |
"net/http" | |
"text/template" | |
"websocket" | |
) | |
var addr = flag.String("addr", ":8080", "http service address") | |
func main() { | |
flag.Parse() | |
go hub() | |
http.HandleFunc("/", homeHandler) | |
http.Handle("/ws", websocket.Handler(clientHandler)) | |
if err := http.ListenAndServe(*addr, nil); err != nil { | |
log.Fatal("ListenAndServe:", err) | |
} | |
} | |
var messageChan = make(chan []byte) | |
type subscription struct { | |
conn *websocket.Conn | |
subscribe bool | |
} | |
var subscriptionChan = make(chan subscription) | |
func hub() { | |
conns := make(map[*websocket.Conn]int) | |
for { | |
select { | |
case subscription := <-subscriptionChan: | |
if subscription.subscribe { | |
conns[subscription.conn] = 0 | |
} else { | |
delete(conns, subscription.conn) | |
} | |
case message := <-messageChan: | |
for conn, _ := range conns { | |
if _, err := conn.Write(message); err != nil { | |
conn.Close() | |
} | |
} | |
} | |
} | |
} | |
func clientHandler(ws *websocket.Conn) { | |
defer func() { | |
subscriptionChan <- subscription{ws, false} | |
ws.Close() | |
}() | |
subscriptionChan <- subscription{ws, true} | |
for { | |
var b []byte | |
err := websocket.Message.Receive(ws, &b) | |
if err != nil { | |
break | |
} | |
messageChan <- b | |
} | |
} | |
// Handle home page requests. | |
func homeHandler(c http.ResponseWriter, req *http.Request) { | |
homeTempl.Execute(c, req.Host) | |
} | |
var homeTempl = template.Must(template.New("home").Parse(` | |
<html> | |
<head> | |
<title>Chat Example</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; | |
} | |
} | |
$("#form").submit(function() { | |
if (!conn) { | |
return false; | |
} | |
if (!msg.val()) { | |
return false; | |
} | |
conn.send(msg.val()); | |
msg.val(""); | |
return false | |
}); | |
if (window["WebSocket"]) { | |
conn = new WebSocket("ws://{{$}}/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; | |
} | |
#form { | |
padding: 0 0.5em 0 0.5em; | |
margin: 0; | |
position: absolute; | |
bottom: 1em; | |
left: 0px; | |
width: 100%; | |
overflow: hidden; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="log"></div> | |
<form id="form"> | |
<input type="submit" value="Send" /> | |
<input type="text" id="msg" size="64"/> | |
</form> | |
</body> | |
</html> `)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
run: clean example | |
./example | |
include $(GOROOT)/src/Make.inc | |
TARG=example | |
GOFILES=\ | |
main.go\ | |
include $(GOROOT)/src/Make.cmd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment