Skip to content

Instantly share code, notes, and snippets.

@ds0nt
Created March 21, 2016 05:43
Show Gist options
  • Save ds0nt/76b4bc3ee34427fba0c6 to your computer and use it in GitHub Desktop.
Save ds0nt/76b4bc3ee34427fba0c6 to your computer and use it in GitHub Desktop.
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