package main
import (
"flag"
"fmt"
"github.com/gorilla/websocket"
"io/ioutil"
"log"
"net/url"
"os"
"os/signal"
"time"
)
var (
argv struct {
host string
key string
help bool
}
)
func processArgs( ) ( needStop bool) {
needStop = true
if argv.help {
flag.Usage ( )
} else if len( argv.host ) == 0 {
fmt.Fprintln ( os.Stderr , "Hey! -host is required" )
flag.Usage ( )
} else if len( argv.key ) == 0 {
fmt.Fprintln ( os.Stderr , "Hey! -key is required" )
flag.Usage ( )
} else {
needStop = false
}
return
}
func init( ) {
flag.StringVar ( & argv.host , `host`, ``, `streaming api host. REQUIRED `)
flag.StringVar ( & argv.key , `key`, ``, `client key. REQUIRED `)
flag.BoolVar ( & argv.help , `h`, false , `show this help`)
flag.Parse ( )
}
func main( ) {
if processArgs( ) {
return
}
u := url.URL { Scheme: "wss" , Host: argv.host , Path: "/stream/" , RawQuery: "key=" + argv.key }
log .
Printf ( "connecting to %s\n " , u.
String ( ) ) c, wsResp, err := websocket.DefaultDialer .Dial ( u.String ( ) , nil)
if err != nil {
if err == websocket.ErrBadHandshake {
log .
Printf ( "handshake failed with status %d\n " , wsResp.
StatusCode ) bodyBuf, _ := ioutil.ReadAll ( wsResp.Body )
log .
Println ( "respBody:" , string
( bodyBuf
) ) }
log .
Fatal ( "dial error:" , err
) }
log .
Println ( "connection established" ) defer c.Close ( )
done := make( chan struct { } )
defer close( done)
go func( ) {
for {
_, message, err := c.ReadMessage ( )
if err != nil {
log .
Println ( "read error:" , err
) done <- struct { } { }
return
}
log .
Printf ( "recv: %s" , string
( message
) ) }
} ( )
interrupt := make( chan os.Signal , 1 )
signal.Notify ( interrupt, os.Interrupt )
select {
case <- interrupt:
err := c.WriteMessage ( websocket.CloseMessage , websocket.FormatCloseMessage ( websocket.CloseNormalClosure , "" ) )
if err != nil {
log .
Println ( "write close error: " , err
) return
}
select {
case <- done:
}
case <- done:
}
}
cGFja2FnZSBtYWluCgppbXBvcnQgKAoJImZsYWciCgkiZm10IgoJImdpdGh1Yi5jb20vZ29yaWxsYS93ZWJzb2NrZXQiCgkiaW8vaW91dGlsIgoJImxvZyIKCSJuZXQvdXJsIgoJIm9zIgoJIm9zL3NpZ25hbCIKCSJ0aW1lIgopCgp2YXIgKAoJYXJndiBzdHJ1Y3QgewoJCWhvc3Qgc3RyaW5nCgkJa2V5ICBzdHJpbmcKCQloZWxwIGJvb2wKCX0KKQoKZnVuYyBwcm9jZXNzQXJncygpIChuZWVkU3RvcCBib29sKSB7CgluZWVkU3RvcCA9IHRydWUKCglpZiBhcmd2LmhlbHAgewoJCWZsYWcuVXNhZ2UoKQoJfSBlbHNlIGlmIGxlbihhcmd2Lmhvc3QpID09IDAgewoJCWZtdC5GcHJpbnRsbihvcy5TdGRlcnIsICJIZXkhIC1ob3N0IGlzIHJlcXVpcmVkIikKCQlmbGFnLlVzYWdlKCkKCX0gZWxzZSBpZiBsZW4oYXJndi5rZXkpID09IDAgewoJCWZtdC5GcHJpbnRsbihvcy5TdGRlcnIsICJIZXkhIC1rZXkgaXMgcmVxdWlyZWQiKQoJCWZsYWcuVXNhZ2UoKQoJfSBlbHNlIHsKCQluZWVkU3RvcCA9IGZhbHNlCgl9CgoJcmV0dXJuCn0KCmZ1bmMgaW5pdCgpIHsKCWZsYWcuU3RyaW5nVmFyKCZhcmd2Lmhvc3QsIGBob3N0YCwgYGAsIGBzdHJlYW1pbmcgYXBpIGhvc3QuIFJFUVVJUkVEYCkKCWZsYWcuU3RyaW5nVmFyKCZhcmd2LmtleSwgYGtleWAsIGBgLCBgY2xpZW50IGtleS4gUkVRVUlSRURgKQoJZmxhZy5Cb29sVmFyKCZhcmd2LmhlbHAsIGBoYCwgZmFsc2UsIGBzaG93IHRoaXMgaGVscGApCgoJZmxhZy5QYXJzZSgpCn0KCmZ1bmMgbWFpbigpIHsKCWlmIHByb2Nlc3NBcmdzKCkgewoJCXJldHVybgoJfQoKCXUgOj0gdXJsLlVSTHtTY2hlbWU6ICJ3c3MiLCBIb3N0OiBhcmd2Lmhvc3QsIFBhdGg6ICIvc3RyZWFtLyIsIFJhd1F1ZXJ5OiAia2V5PSIgKyBhcmd2LmtleX0KCWxvZy5QcmludGYoImNvbm5lY3RpbmcgdG8gJXNcbiIsIHUuU3RyaW5nKCkpCgljLCB3c1Jlc3AsIGVyciA6PSB3ZWJzb2NrZXQuRGVmYXVsdERpYWxlci5EaWFsKHUuU3RyaW5nKCksIG5pbCkKCWlmIGVyciAhPSBuaWwgewoJCWlmIGVyciA9PSB3ZWJzb2NrZXQuRXJyQmFkSGFuZHNoYWtlIHsKCQkJbG9nLlByaW50ZigiaGFuZHNoYWtlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZFxuIiwgd3NSZXNwLlN0YXR1c0NvZGUpCgkJCWJvZHlCdWYsIF8gOj0gaW91dGlsLlJlYWRBbGwod3NSZXNwLkJvZHkpCgkJCWxvZy5QcmludGxuKCJyZXNwQm9keToiLCBzdHJpbmcoYm9keUJ1ZikpCgkJfQoJCWxvZy5GYXRhbCgiZGlhbCBlcnJvcjoiLCBlcnIpCgl9Cglsb2cuUHJpbnRsbigiY29ubmVjdGlvbiBlc3RhYmxpc2hlZCIpCglkZWZlciBjLkNsb3NlKCkKCglkb25lIDo9IG1ha2UoY2hhbiBzdHJ1Y3R7fSkKCWRlZmVyIGNsb3NlKGRvbmUpCgoJZ28gZnVuYygpIHsKCQlmb3IgewoJCQlfLCBtZXNzYWdlLCBlcnIgOj0gYy5SZWFkTWVzc2FnZSgpCgkJCWlmIGVyciAhPSBuaWwgewoJCQkJbG9nLlByaW50bG4oInJlYWQgZXJyb3I6IiwgZXJyKQoJCQkJZG9uZSA8LSBzdHJ1Y3R7fXt9CgkJCQlyZXR1cm4KCQkJfQoJCQlsb2cuUHJpbnRmKCJyZWN2OiAlcyIsIHN0cmluZyhtZXNzYWdlKSkKCQl9Cgl9KCkKCglpbnRlcnJ1cHQgOj0gbWFrZShjaGFuIG9zLlNpZ25hbCwgMSkKCXNpZ25hbC5Ob3RpZnkoaW50ZXJydXB0LCBvcy5JbnRlcnJ1cHQpCglzZWxlY3QgewoJY2FzZSA8LWludGVycnVwdDoKCQlsb2cuUHJpbnRsbigiaW50ZXJydXB0IikKCQllcnIgOj0gYy5Xcml0ZU1lc3NhZ2Uod2Vic29ja2V0LkNsb3NlTWVzc2FnZSwgd2Vic29ja2V0LkZvcm1hdENsb3NlTWVzc2FnZSh3ZWJzb2NrZXQuQ2xvc2VOb3JtYWxDbG9zdXJlLCAiIikpCgkJaWYgZXJyICE9IG5pbCB7CgkJCWxvZy5QcmludGxuKCJ3cml0ZSBjbG9zZSBlcnJvcjogIiwgZXJyKQoJCQlyZXR1cm4KCQl9CgkJc2VsZWN0IHsKCQljYXNlIDwtZG9uZToKCQljYXNlIDwtdGltZS5BZnRlcih0aW1lLlNlY29uZCk6CgkJfQoJY2FzZSA8LWRvbmU6Cgl9Cn0=