Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add chatroulette

  • Loading branch information...
commit ed37cffe6ec3c96712d947ac379c374f112c7718 1 parent 5703ffd
@cespare authored
View
BIN  chat-both/chat-both
Binary file not shown
View
83 chat-both/chat.go
@@ -0,0 +1,83 @@
+package main
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "net/http"
+
+ "code.google.com/p/go.net/websocket"
+)
+
+const listenAddr = "localhost:4000"
+
+func main() {
+ go netListen() // HL
+ http.HandleFunc("/", rootHandler)
+ http.Handle("/socket", websocket.Handler(socketHandler))
+ err := http.ListenAndServe(listenAddr, nil)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+func netListen() {
+ l, err := net.Listen("tcp", "localhost:4001")
+ if err != nil {
+ log.Fatal(err)
+ }
+ for {
+ c, err := l.Accept()
+ if err != nil {
+ log.Fatal(err)
+ }
+ go match(c)
+ }
+}
+
+type socket struct {
+ io.ReadWriter
+ done chan bool
+}
+
+func (s socket) Close() error {
+ s.done <- true
+ return nil
+}
+
+func socketHandler(ws *websocket.Conn) {
+ s := socket{ws, make(chan bool)}
+ go match(s)
+ <-s.done
+}
+
+var partner = make(chan io.ReadWriteCloser)
+
+func match(c io.ReadWriteCloser) {
+ fmt.Fprint(c, "Waiting for a partner...")
+ select {
+ case partner <- c:
+ // now handled by the other goroutine
+ case p := <-partner:
+ chat(p, c)
+ }
+}
+
+func chat(a, b io.ReadWriteCloser) {
+ fmt.Fprintln(a, "Found one! Say hi.")
+ fmt.Fprintln(b, "Found one! Say hi.")
+ errc := make(chan error, 1)
+ go cp(a, b, errc)
+ go cp(b, a, errc)
+ if err := <-errc; err != nil {
+ log.Println(err)
+ }
+ a.Close()
+ b.Close()
+}
+
+func cp(w io.Writer, r io.Reader, errc chan<- error) {
+ _, err := io.Copy(w, r)
+ errc <- err
+}
View
66 chat-both/html.go
@@ -0,0 +1,66 @@
+package main
+
+import "html/template"
+import "net/http"
+
+func rootHandler(w http.ResponseWriter, r *http.Request) {
+ rootTemplate.Execute(w, listenAddr)
+}
+
+var rootTemplate = template.Must(template.New("root").Parse(`
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<script>
+
+var input, output, websocket;
+
+function showMessage(m) {
+ var p = document.createElement("p");
+ p.innerHTML = m;
+ output.appendChild(p);
+}
+
+function onMessage(e) {
+ showMessage(e.data);
+}
+
+function onClose() {
+ showMessage("Connection closed.");
+}
+
+function sendMessage() {
+ var m = input.value;
+ input.value = "";
+ websocket.send(m + "\n");
+ showMessage(m);
+}
+
+function onKey(e) {
+ if (e.keyCode == 13) {
+ sendMessage();
+ }
+}
+
+function init() {
+ input = document.getElementById("input");
+ input.addEventListener("keyup", onKey, false);
+
+ output = document.getElementById("output");
+
+ websocket = new WebSocket("ws://{{.}}/socket");
+ websocket.onmessage = onMessage;
+ websocket.onclose = onClose;
+}
+
+window.addEventListener("load", init, false);
+
+</script>
+</head>
+<body>
+<input id="input" type="text">
+<div id="output"></div>
+</body>
+</html>
+`))
View
43 chat-simple.go
@@ -0,0 +1,43 @@
+package main
+
+import (
+ "fmt"
+ "io"
+ "log"
+ "net"
+)
+
+const listenAddr = "localhost:4000"
+
+func main() {
+ l, err := net.Listen("tcp", listenAddr)
+ if err != nil {
+ log.Fatal(err)
+ }
+ for {
+ c, err := l.Accept()
+ if err != nil {
+ log.Fatal(err)
+ }
+ go match(c) // HL
+ }
+}
+
+var partner = make(chan io.ReadWriteCloser)
+
+func match(c io.ReadWriteCloser) {
+ fmt.Fprint(c, "Waiting for a partner...")
+ select {
+ case partner <- c:
+ // now handled by the other goroutine
+ case p := <-partner:
+ chat(p, c)
+ }
+}
+
+func chat(a, b io.ReadWriteCloser) {
+ fmt.Fprintln(a, "Found one! Say hi.")
+ fmt.Fprintln(b, "Found one! Say hi.")
+ go io.Copy(a, b)
+ io.Copy(b, a)
+}
Please sign in to comment.
Something went wrong with that request. Please try again.