You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一机器多WebSocket客户端连接服务器端口冲突问题求助

问题描述

我在家庭服务器部署了Python WebSocket服务,单客户端连接正常,但同一客户端机器启动多个实例时,必须等第一个客户端断开后,后续实例才能建立连接;不同机器或服务器本地运行多客户端则可正常同时连接。经netstat排查,客户端本地端口各不相同,但外发的远程端口均固定为服务器WebSocket端口3000,导致连接冲突。因无法修改客户端代码,需从系统或服务器端解决该问题。设备环境:客户端为Fedora 39(KDE Plasma),服务器为RHEL系操作系统。

服务器代码如下:

import asyncio
import websockets


# identifies the port
PORT = "3000"

# identifies the hostname
HOST = "rx-78-2"

# sets the trust message that essentially acts as a secondary handshake
TURTLE_MESSAGE = "Shake my hand bro"

# sets the message that will indicate a disconnection 
DISCONNECT_MESSAGE = "END-OF-LINE"

turtles = []

# handles a new connection
async def handle_connect(websocket, path):
    print(f"CONNECTION RECIEVED @ {path}")
    turtleIndex = len(turtles)
    turtles.append(f"Turtle {len(turtles)}")

    print(turtles[turtleIndex])


    connected = True

    first_msg = await websocket.recv()
    if first_msg != TURTLE_MESSAGE:
        print("Connection Refused")
        await websocket.send("return print('Connection Refused')")
        await websocket.close()
    else:
        print("Connection Established")
        await websocket.send("return print('Connection Established')")

    while connected:
        msg = await websocket.recv()
        if msg == DISCONNECT_MESSAGE:
            break
        print(msg)
        await websocket.send("return turtle.turnRight()")

    print("CLOSING SOCKET")

async def main():
    async with websockets.serve(handle_connect, HOST, PORT, ssl=None, compression=None):
        await asyncio.Future()

print("STARTING SERVER")
asyncio.run(main())
解决方案

1. 调整服务器绑定IP

当前代码中HOST = "rx-78-2"仅绑定到服务器主机名对应的特定IP,可能导致同一客户端多实例连接时出现异常。修改为监听所有网卡:

HOST = "0.0.0.0"

重启WebSocket服务后测试连接。

2. 优化服务器系统参数

提升文件描述符限制

WebSocket连接依赖系统文件描述符,默认限制可能过低,无法支撑多并发连接:

  • 临时生效:执行ulimit -n 65535(仅当前会话有效)
  • 永久生效:编辑/etc/security/limits.conf,添加以下内容:
    * soft nofile 65535
    * hard nofile 65535
    
    重启服务器后生效。

增大TCP半连接队列

调整tcp_max_syn_backlog参数,避免客户端SYN请求被丢弃:

  • 临时生效:sysctl -w net.ipv4.tcp_max_syn_backlog=4096
  • 永久生效:编辑/etc/sysctl.conf,添加net.ipv4.tcp_max_syn_backlog = 4096,执行sysctl -p使配置生效。

3. 优化客户端机器(Fedora 39)TCP参数

开启TIME_WAIT端口复用

允许处于TIME_WAIT状态的端口被快速复用,缓解同一客户端多实例的连接冲突:

  • 临时生效:
    sysctl -w net.ipv4.tcp_tw_reuse=1
    sysctl -w net.ipv4.tcp_fin_timeout=30
    
  • 永久生效:编辑/etc/sysctl.conf,添加:
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_fin_timeout = 30
    
    执行sysctl -p使配置生效。

扩大本地端口范围

增加客户端可用的本地端口数量,避免端口耗尽:

  • 临时生效:sysctl -w net.ipv4.ip_local_port_range="1024 65535"
  • 永久生效:编辑/etc/sysctl.conf,添加net.ipv4.ip_local_port_range = 1024 65535,执行sysctl -p使配置生效。

4. 服务器端部署负载均衡(可选)

若上述方法无效,可通过Nginx实现负载均衡,将客户端请求分发到多个WebSocket服务实例:

  1. 启动多个WebSocket服务实例,分别绑定3001、3002等不同端口
  2. 配置Nginx:
    http {
        upstream websocket_backend {
            server 127.0.0.1:3001;
            server 127.0.0.1:3002;
        }
    
        server {
            listen 3000;
    
            location / {
                proxy_pass http://websocket_backend;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $host;
            }
        }
    }
    
  3. 重启Nginx服务,客户端仍连接3000端口即可实现并发连接。

内容的提问来源于stack exchange,提问作者BlackDiamond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:51:02