Go协程 – 为什么WebSocket报告连接已关闭?

huangapple go评论82阅读模式
英文:

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

Error

 t.go:21] read tcp 127.0.0.1:12345-&gt;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 &quot;github.com/golang/glog&quot;
&quot;net/http&quot;
&quot;golang.org/x/net/websocket&quot;
&quot;time&quot;
&quot;flag&quot;
)
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, &amp;msg); err != nil {
log.Exit(err)
}
srv.payload &lt;- msg 
return
}
// This example demonstrates a trivial client/ server.
func main() {
flag.Parse()
srv := server{payload: make(chan string, 10)}
go func() {
http.Handle(&quot;/echo&quot;, websocket.Handler(srv.serve))
err := http.ListenAndServe(&quot;:12345&quot;, nil)
if err != nil {
log.Errorf(&quot;ListenAndServe: &quot; + err.Error())
}
}()
// give the server some time to start listening
time.Sleep(3 *time.Second)
//dial and test the response.
ws, err := websocket.Dial(&quot;ws://localhost:12345/echo&quot;, &quot;&quot;, &quot;http://localhost/?x=45&quot;)
if err != nil {
log.Exit(err)
}
ms := &quot;test&quot;
if err := websocket.Message.Send(ws, ms); err != nil {
log.Exit(err)
}
msg := &lt;-srv.payload
if msg != ms{
log.Errorf(&quot;msg %v is not %v&quot;, ms)
}
}

答案1

得分: 1

websocket服务器在处理程序返回时会关闭连接。删除Go例程是正确的修复方法。

英文:

The websocket server closes the connection when the handler returns.

Removing the Go routine is the correct fix.

huangapple
  • 本文由 发表于 2015年8月7日 14:03:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/31870743.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定