dongqiuxu2270
2015-08-07 06:03
浏览 168
已采纳

进入例行程序-为什么websocket将连接报告为已关闭?

I'm trying to create a client and a server using Go but for some reason the server reports the connection as "closed". As the code is trivial I can't think of anything wrong with my code. Any help is appreciated.

package main

import (
    log "github.com/golang/glog"
    "net/http"
    "golang.org/x/net/websocket"
    "time"
    "flag"
)

type server struct {
    payload chan string
}

// srv pushes the messages received via ws into srv.payload
func (srv *server) serve(ws *websocket.Conn) {
    go func() {
        var msg string
        if err := websocket.Message.Receive(ws, &msg); err != nil {
            log.Exit(err)
        }
        srv.payload <- msg
    }()
    return
}

// This example demonstrates a trivial client/ server.
func main() {
    flag.Parse()
    srv := server{payload: make(chan string, 10)}
    http.Handle("/echo", websocket.Handler(srv.serve))
    go func() {
        err := http.ListenAndServe(":12345", nil)
        if err != nil {
            log.Errorf("ListenAndServe: " + err.Error())
        }
    }()
    // give the server some time to start listening
    time.Sleep(3 *time.Second)
    //dial and test the response.
    ws, err := websocket.Dial("ws://localhost:12345/echo", "", "http://localhost/?x=45")
    if err != nil {
        log.Exit(err)
    }
    ms := "test"
    if err := websocket.Message.Send(ws, ms); err != nil {
        log.Exit(err)
    }
    msg := <-srv.payload
    if msg != ms{
        log.Errorf("msg %v is not %v", ms)
    }

}

Error

 t.go:21] read tcp 127.0.0.1:12345->127.0.0.1:43135: 

Edit: After some try and error I've found that if I remove the go routine from the serve method it works but it doesn't make sense to me. Any idea why it doesn't work when websocket.Message.Receive is in a separate go routine?

package main

import (
    log "github.com/golang/glog"
    "net/http"
    "golang.org/x/net/websocket"
    "time"
    "flag"
)

type server struct {
    payload chan string
}

// srv pushes the messages received via ws into srv.payload
func (srv *server) serve(ws *websocket.Conn) {
        var msg string
        if err := websocket.Message.Receive(ws, &msg); err != nil {
            log.Exit(err)
        }
        srv.payload <- msg 
    return
}

// This example demonstrates a trivial client/ server.
func main() {
    flag.Parse()
    srv := server{payload: make(chan string, 10)}

    go func() {
        http.Handle("/echo", websocket.Handler(srv.serve))
        err := http.ListenAndServe(":12345", nil)
        if err != nil {
            log.Errorf("ListenAndServe: " + err.Error())
        }
    }()
    // give the server some time to start listening
    time.Sleep(3 *time.Second)
    //dial and test the response.
    ws, err := websocket.Dial("ws://localhost:12345/echo", "", "http://localhost/?x=45")
    if err != nil {
        log.Exit(err)
    }
    ms := "test"
    if err := websocket.Message.Send(ws, ms); err != nil {
        log.Exit(err)
    }
    msg := <-srv.payload
    if msg != ms{
        log.Errorf("msg %v is not %v", ms)
    }

}
  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doudi5892 2015-08-07 13:23
    已采纳

    The websocket server closes the connection when the handler returns.

    Removing the Go routine is the correct fix.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题