在AWS Application Load Balancer上使用Go时,WebSocket连接失败并显示301

I'm trying to run a Go Server with WebSockets on an AWS Application Load Balancer but I am getting an 'Error during WebSocket handshake: Unexpected response code: 301'.

AWS says that The Application Load Balancers supports WebSockets via ws:// protocols but I can not find any further documentation other than the following:

Here's aws load-balancer link

The Application Load Balancer supports two additional protocols: WebSocket and HTTP/2.

WebSocket allows you to set up long-standing TCP connections between your client and your server. This is a more efficient alternative to the old-school method which involved HTTP connections that were held open with a “heartbeat” for very long periods of time. WebSocket is great for mobile devices and can be used to deliver stock quotes, sports scores, and other dynamic data while minimizing power consumption. ALB provides native support for WebSocket via the ws:// and wss:// protocols.

I can get JavaScript to connect to my Go server via WebSockets locally but when I deploy AWS it does not work. This is when the JavaScript displays a 301 error.

The Application Load Balancer is listening on HTTP: 80 and that traffic is being directed to HTTPS: 443. All of the Security Groups are pretty much similarly set up to allow traffic through. If I do a normal GET call to retrieve data from my server while deployed on AWS it works perfectly fine.

Local call that works to connect to localhost

<script>
    let socket = new WebSocket("ws://localhost:8080/websocket")

    console.log("Attempting Websocket Connection")

    socket.onopen = () => {
        console.log("Successfully Connected");
        socket.send("Hi From the Client!")
    }

    socket.onclose = (event) => {
        console.log("Socket Closed Connection: ", event)
    }

    socket.onmessage = (msg) => {
        console.log(msg);
    }

    socket.onerror = (error) => {
        console.log("Socket Error: ", error)
    }
</script>

Connect to remote server that does not work.

<script>
    let socket = new WebSocket("ws://myexamplesite.com/websocket")

    console.log("Attempting Websocket Connection")

    socket.onopen = () => {
        console.log("Successfully Connected");
        socket.send("Hi From the Client!")
    }

    socket.onclose = (event) => {
        console.log("Socket Closed Connection: ", event)
    }

    socket.onmessage = (msg) => {
        console.log(msg);
    }

    socket.onerror = (error) => {
        console.log("Socket Error: ", error)
    }
</script>

nginx.conf

events {
    worker_connections 1024;
}

http {
  server_tokens off;
  server {
    listen 80;

    location / {
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header Host            $http_host;
      proxy_pass http://web:8080/;
    }
  }
}

I expect to be able to establish a WebSocket connection but the following error is returning from the JavaScript file:

WebSocket connection to 'ws://myexamplesite.com/websocket' failed: Error during WebSocket handshake: Unexpected response code: 301

douwen3362
douwen3362 谢谢你的工作!
大约一年之前 回复
douren2395
douren2395 “将流量定向到HTTPS”大概是指重定向,如果这样,则可以很好地解释您为什么获得301的原因。将Web套接字URL更改为wss://-让socket=newWebSocket(“wss://。...
大约一年之前 回复

2个回答

I was able to get it to work by combining both answers.

nginx.conf now looks like

http {
  server_tokens off;
  server {
    listen 80;

    location / {
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_set_header Host            $http_host;
      proxy_pass http://web:8080/;
    }

    location /websocket {
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           proxy_pass http://web:8080/websocket;
    }
  }
}

Then change the JavaScript file ws:// to wss://

<script>
    let socket = new WebSocket("wss://myexamplesite.com/websocket")

    console.log("Attempting Websocket Connection")

    socket.onopen = () => {
        console.log("Successfully Connected");
        socket.send("Hi From the Client!")
    }

    socket.onclose = (event) => {
        console.log("Socket Closed Connection: ", event)
    }

    socket.onmessage = (msg) => {
        console.log(msg);
    }

    socket.onerror = (error) => {
        console.log("Socket Error: ", error)
    }
</script>



首先检查您在AWS ALB配置方面是否一切正确,并且请求已到达Nginx服务器,您可以在 日志。 另外,请尝试通过Nginx访问您的websocket URL。 您需要在Nginx中进行其他配置,以支持您所在位置的websocket,如此处所述:</ p>

  proxy_set_header升级$ http_upgrade; 
proxy_set_header连接“升级”;
</ code> < / pre>

我遇到了同样的问题,使用此配置东西开始像微风一样工作。</ p>

参考: Nginx WebSocket代理 </ p>

注意</ strong>:Websockets可以工作 当然可以使用AWS ALB,所以请不要怀疑该部分。</ p>
</ div>

展开原文

原文

First check that you have everything correct in terms of AWS ALB config and the requests are reaching the Nginx server, which you can check in the logs. Also try to hit your websocket URL through Nginx. You need an additional config in Nginx to support websockets under your location as mentioned here :

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

I have experienced the same issue and using this config thing started to work like a breeze.

Reference : Nginx WebSocket proxying

Note: Websockets work with AWS ALB for sure, so don't doubt that part.

doulao5916
doulao5916 优秀的.......
大约一年之前 回复
dongying3830
dongying3830 这部分工作还必须将ws://更改为wss://
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐