英文:
go routine - why websocket reports the connection as closed?
问题
我正在尝试使用Go创建一个客户端和服务器,但出于某种原因,服务器报告连接为“closed”。由于代码很简单,我无法想到代码有什么问题。希望能得到帮助。
错误信息:
t.go:21] read tcp 127.0.0.1:12345->127.0.0.1:43135:
编辑:
经过一些尝试和错误,我发现如果我从serve方法中删除go例程,它就可以工作,但这对我来说没有意义。有任何想法为什么当websocket.Message.Receive在单独的go例程中时它不起作用?
以下是翻译好的代码:
package main
import (
log "github.com/golang/glog"
"net/http"
"golang.org/x/net/websocket"
"time"
"flag"
)
type server struct {
payload chan string
}
// srv将通过ws接收到的消息推送到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
}
// 这个示例演示了一个简单的客户端/服务器。
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())
}
}()
// 给服务器一些时间来开始监听
time.Sleep(3 * time.Second)
// 拨号并测试响应。
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)
}
}
修改后的代码:
package main
import (
log "github.com/golang/glog"
"net/http"
"golang.org/x/net/websocket"
"time"
"flag"
)
type server struct {
payload chan string
}
// srv将通过ws接收到的消息推送到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
}
// 这个示例演示了一个简单的客户端/服务器。
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())
}
}()
// 给服务器一些时间来开始监听
time.Sleep(3 * time.Second)
// 拨号并测试响应。
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)
}
}
英文:
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
得分: 1
websocket服务器在处理程序返回时会关闭连接。删除Go例程是正确的修复方法。
英文:
The websocket server closes the connection when the handler returns.
Removing the Go routine is the correct fix.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论