|
|
@@ -0,0 +1,153 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "flag"
|
|
|
+ "html/template"
|
|
|
+ "log"
|
|
|
+ "net/http"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/gorilla/websocket"
|
|
|
+)
|
|
|
+
|
|
|
+var addr = flag.String("addr", "localhost:8080", "http service address")
|
|
|
+
|
|
|
+var upgrader = websocket.Upgrader{} // use default options
|
|
|
+
|
|
|
+func echo(w http.ResponseWriter, r *http.Request) {
|
|
|
+ c, err := upgrader.Upgrade(w, r, nil)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ log.Print("upgrade:", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ defer c.Close()
|
|
|
+
|
|
|
+ // 设置心跳处理
|
|
|
+ c.SetPongHandler(func(message string) error {
|
|
|
+ log.Println("pong received:", message)
|
|
|
+ return err
|
|
|
+ })
|
|
|
+
|
|
|
+ go func() {
|
|
|
+ // 设定ping
|
|
|
+ pingTimer := time.NewTicker(10 * time.Second)
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case <-pingTimer.C:
|
|
|
+ go func() {
|
|
|
+ log.Println("ping msg")
|
|
|
+ err := c.WriteControl(websocket.PingMessage, []byte("Do ping"), time.Now().Add(time.Second))
|
|
|
+ if err != nil {
|
|
|
+ log.Println(err)
|
|
|
+ }
|
|
|
+ }()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ for {
|
|
|
+ mt, message, err := c.ReadMessage()
|
|
|
+ if err != nil {
|
|
|
+ log.Println("read:", err)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ log.Printf("recv: %s", message)
|
|
|
+ err = c.WriteMessage(mt, message)
|
|
|
+ if err != nil {
|
|
|
+ log.Println("write:", err)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func home(w http.ResponseWriter, r *http.Request) {
|
|
|
+ homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
|
|
|
+}
|
|
|
+
|
|
|
+func main() {
|
|
|
+ flag.Parse()
|
|
|
+ log.SetFlags(0)
|
|
|
+ http.HandleFunc("/echo", echo)
|
|
|
+ http.HandleFunc("/", home)
|
|
|
+ log.Fatal(http.ListenAndServe(*addr, nil))
|
|
|
+}
|
|
|
+
|
|
|
+var homeTemplate = template.Must(template.New("").Parse(`
|
|
|
+<!DOCTYPE html>
|
|
|
+<html>
|
|
|
+<head>
|
|
|
+<meta charset="utf-8">
|
|
|
+<script>
|
|
|
+window.addEventListener("load", function(evt) {
|
|
|
+
|
|
|
+ var output = document.getElementById("output");
|
|
|
+ var input = document.getElementById("input");
|
|
|
+ var ws;
|
|
|
+
|
|
|
+ var print = function(message) {
|
|
|
+ var d = document.createElement("div");
|
|
|
+ d.textContent = message;
|
|
|
+ output.appendChild(d);
|
|
|
+ };
|
|
|
+
|
|
|
+ document.getElementById("open").onclick = function(evt) {
|
|
|
+ if (ws) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ ws = new WebSocket("{{.}}");
|
|
|
+ ws.onopen = function(evt) {
|
|
|
+ print("OPEN");
|
|
|
+ }
|
|
|
+ ws.onclose = function(evt) {
|
|
|
+ print("CLOSE");
|
|
|
+ ws = null;
|
|
|
+ }
|
|
|
+ ws.onmessage = function(evt) {
|
|
|
+ print("RESPONSE: " + evt.data);
|
|
|
+ }
|
|
|
+ ws.onerror = function(evt) {
|
|
|
+ print("ERROR: " + evt.data);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+ document.getElementById("send").onclick = function(evt) {
|
|
|
+ if (!ws) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ print("SEND: " + input.value);
|
|
|
+ ws.send(input.value);
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+ document.getElementById("close").onclick = function(evt) {
|
|
|
+ if (!ws) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ ws.close();
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+});
|
|
|
+</script>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+<table>
|
|
|
+<tr><td valign="top" width="50%">
|
|
|
+<p>Click "Open" to create a connection to the server,
|
|
|
+"Send" to send a message to the server and "Close" to close the connection.
|
|
|
+You can change the message and send multiple times.
|
|
|
+<p>
|
|
|
+<form>
|
|
|
+<button id="open">Open</button>
|
|
|
+<button id="close">Close</button>
|
|
|
+<p><input id="input" type="text" value="Hello world!">
|
|
|
+<button id="send">Send</button>
|
|
|
+</form>
|
|
|
+</td><td valign="top" width="50%">
|
|
|
+<div id="output"></div>
|
|
|
+</td></tr></table>
|
|
|
+</body>
|
|
|
+</html>
|
|
|
+`))
|