您如何对WebSocket服务器进行docker化?

我在将WebSocket服务器放入Docker容器时遇到麻烦。

这是服务器代码,它使用“ connected”写入新连接。

// server.go

func RootHandler(w http.ResponseWriter, r *http.Request) {

upgrader := websocket.Upgrader{ // (Uses gorilla/websocket)

ReadBufferSize: 4096,

WriteBufferSize: 4096,

}

conn, err := upgrader.Upgrade(w, r, nil)

if err != nil {

panic(err)

}

if err = conn.WriteMessage(websocket.TextMessage, []byte("connected")); err != nil {

panic(err)

}

}

func main() {

fmt.Println("server is running")

// For graceful shutdown

stop := make(chan os.Signal, 1)

signal.Notify(stop, os.Interrupt)

server := http.Server{Addr: "localhost:8000"}

defer server.Close()

http.HandleFunc("/", RootHandler)

go func() {

err := server.ListenAndServe()

if err != nil && err != http.ErrServerClosed {

panic(err)

}

}()

<-stop

}

这是客户:

// client.go

func main() {

connection, _, err := websocket.DefaultDialer.Dial("ws://localhost:8000", nil)

if err != nil {

panic(err)

}

_, b, err := connection.ReadMessage()

if err != nil {

panic(err)

}

fmt.Println(string(b)) // "connected"

}

运行,server.go然后client.go打印“已连接”,表明代码正在工作。现在,我想将服务器放入Docker容器中。这是dockerfile

FROM golang:1.11.4-alpine3.8

COPY . $GOPATH/src/websocket-test

WORKDIR $GOPATH/src/websocket-test

RUN ["go", "build", "server.go"]

EXPOSE 8000

CMD ["./server"]

我使用这些命令来构建和启动容器,暴露8000 / tcp。

docker build -t websocket-test .

docker run -p 8000:8000 websocket-test

我可以确认服务器正在运行,因为它会显示“服务器正在运行”。如果我是从client.go容器外部开始的,它将感到恐慌:

panic: read tcp [::1]:60328->[::1]:8000: read: connection reset by peer

我期望的结果与以前相同-在客户端打印“已连接”。该错误消息表示服务器在握手之前断开了连接。我不明白“

60328”的数字。据我所知,WebSocket不会在升级时更改端口,因此我应该可以只暴露8000。

我不知道必须更改什么才能通过WebSocket连接到我的服务器。

回答:

当您指定要监听的主机名或IP地址(在这种情况下localhost解析为127.0.0.1)时,服务器将仅监听该IP地址。

localhost当您在Docker容器之外时,侦听不是问题。如果您的服务器仅侦听127.0.0.1:8000,则您的客户端可以轻松连接到该服务器,因为该连接也是从进行的127.0.0.1

当您在Docker容器中运行服务器时,它只会127.0.0.1:8000像以前一样监听。该127.0.0.1是本地环回地址,它无法访问外的容器。

当您使用来启动Docker容器时-p

8000:8000,它会将流量转发127.0.0.1:8000到该容器的IP地址,在我的情况下为172.17.0.2

容器在docker0网络接口内获取IP地址(您可以通过ip addr ls命令查看)

因此,当您的流量转发到上的容器时172.17.0.2:8000,那里没有任何监听,并且连接尝试失败。

解决方法:

问题在于侦听地址:

server := http.Server{Addr: "localhost:8000"}

要解决您的问题,请将其更改为

server := http.Server{Addr: ":8000"}

这将使您的服务器侦听其容器的所有IP地址。

附加信息:

当您在Docker容器中公开端口时,Docker将创建iptables规则来进行实际转发。看到这个。您可以使用以下方法查看这些规则:

iptables -n -L 

iptables -t nat -n -L

以上是 您如何对WebSocket服务器进行docker化? 的全部内容, 来源链接: utcz.com/qa/434924.html

回到顶部