Created
March 21, 2016 05:43
-
-
Save ds0nt/76b4bc3ee34427fba0c6 to your computer and use it in GitHub Desktop.
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 ( | |
"bufio" | |
"encoding/json" | |
"flag" | |
"fmt" | |
"log" | |
"net/url" | |
"os" | |
"os/signal" | |
"time" | |
"github.com/gorilla/websocket" | |
) | |
var addr = flag.String("addr", "forky.io:8081", "http service address") | |
var mapID = flag.String("map", "", "map id") | |
var token = flag.String("token", "", "api token") | |
type AuthPacket struct { | |
Token string `json:"token"` | |
Map string `json:"map"` | |
} | |
func main() { | |
flag.Parse() | |
log.SetFlags(0) | |
interrupt := make(chan os.Signal, 1) | |
signal.Notify(interrupt, os.Interrupt) | |
u := url.URL{Scheme: "ws", Host: *addr, Path: "/"} | |
log.Printf("connecting to %s", u.String()) | |
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) | |
if err != nil { | |
log.Fatal("dial:", err) | |
} | |
defer c.Close() | |
done := make(chan struct{}) | |
c.WriteJSON(AuthPacket{ | |
Map: *mapID, | |
Token: *token, | |
}) | |
go func() { | |
defer c.Close() | |
defer close(done) | |
for { | |
_, message, err := c.ReadMessage() | |
if err != nil { | |
log.Println("read:", err) | |
return | |
} | |
log.Printf("recv: %s", message) | |
} | |
}() | |
msgChan := messages() | |
ticker := time.NewTicker(time.Second) | |
defer ticker.Stop() | |
for { | |
select { | |
case <-ticker.C: | |
if err := c.WriteMessage(websocket.PingMessage, []byte{}); err != nil { | |
return | |
} | |
case <-interrupt: | |
log.Println("interrupt") | |
// To cleanly close a connection, a client should send a close | |
// frame and wait for the server to close the connection. | |
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) | |
if err != nil { | |
log.Println("write close:", err) | |
return | |
} | |
select { | |
case <-done: | |
case <-time.After(time.Second): | |
} | |
c.Close() | |
return | |
case msg, ok := <-msgChan: | |
if !ok { | |
log.Println("No more messages to send.") | |
return | |
} | |
if err := c.WriteJSON(msg); err != nil { | |
return | |
} | |
} | |
} | |
} | |
type SendMessage struct { | |
Type string `json:"type"` | |
Data string `json:"data"` | |
} | |
type mapOp struct { | |
Version int `json:"v"` | |
Operation int `json:"op"` | |
// args | |
A string `json:"a"` | |
B string `json:"b"` | |
} | |
type mapChat struct { | |
Message string `json:"message"` | |
} | |
func messages() <-chan interface{} { | |
out := make(chan interface{}) | |
go func() { | |
defer close(out) | |
scanner := bufio.NewScanner(os.Stdin) | |
for scanner.Scan() { | |
data, _ := json.Marshal(mapChat{ | |
Message: scanner.Text(), | |
}) | |
out <- SendMessage{ | |
Type: "chat", | |
Data: string(data), | |
} | |
} | |
if err := scanner.Err(); err != nil { | |
fmt.Fprintln(os.Stderr, "reading standard input:", err) | |
} | |
}() | |
return out | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment