2016-08-10 24 views
0

新しいgopherがここにあります。限られた経験。WebSocket接続を試行したときに予期しない応答コードが発生する

私はウェブソケットを探索する本を通過しています。私は本からの例で簡単なチャットアプリを組み立てていると私は実行したときには、私は次のエラーを打つ:

WebSocket connection to 'ws://localhost:5000/room' failed: Error during WebSocket handshake: Unexpected response code: 200

誰がこれを原因を知っていますか?

main.go

package main 

import (
    "html/template" 
    "log" 
    "net/http" 
    "path/filepath" 
    "sync" 
) 

type templateHandler struct { 
    //once is an object that will perform exactly one action 
    once  sync.Once 
    filename string 
    templ *template.Template 
} 

func (t *templateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    //this function call will be executed only once 
    t.once.Do(func() { 
     t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename))) 
     log.Println("one time") 
    }) 
    t.templ.Execute(w, nil) 
} 

func main() { 
    http.Handle("/", &templateHandler{filename: "chat.html"}) 
    if err := http.ListenAndServe(":5000", nil); err != nil { 
     log.Fatal("ListenAndServe", err) 
    } 
} 

client.go

package main 

//Notes on channels 
//read from channel x to a 
//a := <- x 
//write 5 to channel x 
//x <- 5 

import (
    "github.com/gorilla/websocket" 
) 

//client represents a single chatting user. 

type client struct { 
    //client represents a single chatting user 
    socket *websocket.Conn 
    //sent is a channel on which messages are sent 
    send chan []byte 
    //room is the room this client is chatting in 
    room *room 
} 

func (c *client) read() { 
    for { 
     //if err is nil after the execution of ReadMessage() 
     //execute the line between the braces 
     if _, msg, err := c.socket.ReadMessage(); err == nil { 
      c.room.forward <- msg 
     } else { 
      break 
     } 
    } 
    c.socket.Close() 
} 

func (c *client) write() { 
    for msg := range c.send { 
     if err := c.socket.WriteMessage(websocket.TextMessage, msg); err != nil { 
      break 
     } 
    } 
    c.socket.Close() 
} 

room.go

package main 

import (
    "log" 
    "net/http" 

    "github.com/gorilla/websocket" 
) 

type room struct { 
    //forward is a channel that holds incoming messages 
    //that should be forwarded to other clients 
    forward chan []byte 
    //join is a channel for clients wishing to join the room 
    join chan *client 
    //leave is a channel for clients wishing to leave the room. 
    leave chan *client 
    //clients holds al the current clients in this room. 
    clients map[*client]bool 
} 

func (r *room) run() { 
    for { 
     select { 
     case client := <-r.join: 
      //joining 
      r.clients[client] = true 
     case client := <-r.leave: 
      //leaving 
      delete(r.clients, client) 
      close(client.send) 
     case msg := <-r.forward: 
      //forward message to all clients 
      for client := range r.clients { 
       select { 
       case client.send <- msg: 
       default: 
        //failed to send 
        delete(r.clients, client) 
        close(client.send) 
       } 
      } 
     } 
    } 
} 

const (
    socketBufferSize = 1024 
    messageBufferSize = 256 
) 

//in order for the browser to switch to the websocket 
//protocol a header with an upgrade request from http 
//to websocket must be sent 
var upgrader = &websocket.Upgrader{ 
    ReadBufferSize: socketBufferSize, 
    WriteBufferSize: socketBufferSize, 
} 

func (r *room) ServeHTTP(w http.ResponseWriter, req *http.Request) { 
    socket, err := upgrader.Upgrade(w, req, nil) 
    if err != nil { 
     log.Fatal("ServeHTTP:", err) 
     return 
    } 
    client := &client{ 
     socket: socket, 
     send: make(chan []byte, messageBufferSize), 
     room: r, 
    } 

    r.join <- client 
    defer func() { r.leave <- client }() 
    go client.write() 
    client.read() 
} 

chat.html

<!DOCTYPE html> 
<html> 
<head> 
    <title>Chat</title> 
<style> 
input {display:block;} 
ul{list-style:none;} 
</style> 

</head> 
<body> 
    <ul id="messages"></ul> 
    <form id="chatbox"> 
     <textarea></textarea> 
     <input type="submit" value="Send" /> 
    </form> 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> 
    </script> 

    <script> 
$(function(){ 
    var socket = null; 
    var msgBox = $("#chatbox textarea"); 
    var messages = $("#messages"); 
    $("#chatbox").submit(function(){ 
     if (!msgBox.val()) return false; 
     if (!socket) { 
      alert("Error: There is no socket connection."); 
      return false; 
     } 
     socket.send(msgBox.val()); 
     msgBox.val(""); 
     return false; 
    }); 
    if (!window["WebSocket"]) { 
     alert("Error: Your browser does not support web sockets.") 
    }else { 
     socket = new WebSocket("ws://localhost:5000/room"); 
     socket.onclose = function() { 
      alert("Connection has been closed."); 
     } 
     socket.onmessage = function(e) { 
      messages.append($("<li>").text(e.data)); 
     } 
    } 
}); 
    </script> 
</body> 
</html> 

答えて

2

ルームハンドラがマルチプレクサに登録されていないという問題があります。すべてのリクエストは、main.goの/のハンドラによって処理されます。 room値をintializeとMOXに登録するコードを追加し、この問題を解決するには

func main() { 
    http.Handler("/room", &room{ 
    forward: make(chan []byte), 
    join: make(chan *client), 
    leave: make(chan *client), 
    clients: make(map[*client]bool), 
    }) 
    http.Handle("/", &templateHandler{filename: "chat.html"}) 
    if err := http.ListenAndServe(":5000", nil); err != nil { 
    log.Fatal("ListenAndServe", err) 
    } 
} 
+0

OMG!トータル脳波!もちろん... 今私はとても愚かな気がする。ありがとう。 – user3017869

関連する問題