当前位置: 首页 > 面试题库 >

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

邹英悟
2023-03-14
问题内容

我在将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服务器实现,继承自Co\Http\Server,底层提供了对WebSocket协议的支持,在此不再赘述,只说差异。 !> 此章节在v4.4.13后可用。 完整示例 Co\run(function () { $server = new Co\Http\Server("127.0.0.1", 9502, false); $server->handle

  • 程序代码 ws_server.php //创建websocket服务器对象,监听0.0.0.0:9502端口 $ws = new Swoole\WebSocket\Server("0.0.0.0", 9502); //监听WebSocket连接打开事件 $ws->on('open', function ($ws, $request) { var_dump($request->fd, $r

  • 开发者可以在游戏进程中启动一个 WebSocket 服务器,提供 RPC 接口。通过完善和调用这些 RPC 接口,开发者能够对游戏进程内部状态进行监控,增加对游戏进程状态的管理能力。 如何启用 WebSocket 服务器 默认是剔除的,需要设置宏 USE_WEBSOCKET_SERVER = 1 以启用。可以通过以下两种方式启用。 方式 1:全平台启用——修改默认值 在 ccConfig.h 中,

  • 问题内容: 您应该在服务器端进行验证,还是可以在客户端进行验证? @TheTXI 我很高兴您感到惊讶,我只是不想遗漏任何可能改变某人答案的虚假信息。 似乎很多人都在关注我要追求的目标,但是应该将Ajax的一部分保留在我的问题中,因为这是最重要的部分。 但是,我阅读这些帖子后知道,一个坏人可以轻松地加载萤火虫并将我的按钮更改为“提交”按钮并进行发布。或其他方式。 问题答案: 浏览器/客户端验证很方便

  • 问题内容: 我有一个在Firebase上编写的应用程序。安全规则和客户端代码还不足以使我的应用正常工作。我需要连接服务器来执行一些任务: 清理非规范化的数据,这对于使用onDisconnect处理程序进行清理具有挑战性 建立数据的其他索引,这超出了 查询的能力范围 问题答案: _更新日期(20160611):如果您在https://firebase.google.com上创建了项目,则从服务器访问

  • 问题内容: 是否有任何教程或指南显示如何用PHP编写一个简单的Websockets服务器?我曾尝试在Google上寻找它,但没有找到很多。我找到了phpwebsockets,但是现在已经过时了,不支持最新的协议。我尝试自己更新它,但似乎不起作用。 和客户: 如果我的代码有任何错误,您可以帮我解决它吗?Firefox中的Concole说 问题答案: 我和您最近在同一条船上,这是我的工作: 1)我使用