使用自定义域名在Google Compute Engine上进行Websocket连接 [英] Websocket connection on Google Compute Engine using a custom domain name

查看:54
本文介绍了使用自定义域名在Google Compute Engine上进行Websocket连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个websocket服务器(node.js),可以在localhost和以前的heroku部署上正常运行.我现在正在迁移到Google计算引擎,并遇到了一些问题.

I have a websocket server (node.js) which runs fine on localhost and on a previous heroku deployment. I am now migrating to google compute engine and running into some issues.

websocket握手失败,返回301错误.正如此答案中指出的,这可能是由于请求通过了不支持Websocket连接的前端服务器而导致的.可以通过直接定位 ws://my_external_gce_ip 来解决.我想知道是否可以更新一些负载平衡配置,以便可以使用自定义域名访问后端.

The websocket handshake is failing returning a 301 error. As pointed out in this answer this can be due to the request going through front end servers that do not support a websocket connection and can be worked around by targeting ws://my_external_gce_ip directly. I am wondering if there is some load balancing configuration I can update so that I can address my backend using the custom domain name.

虽然我了解问题所在,但在我看来,应该在dns查找之后将域解析为外部ip,这样我才不会真正理解约束.

While I understand the problem, it seems to me that the domain should be resolved to the external ip after a dns lookup so I don't understand the constraint really.

很抱歉,如果这很明显.我是GCE的新手,并且整日都在搜寻Google,以获取此信息.我将在下面粘贴我的代码以及NGINX配置,但是我认为这两个都不是特别有用,因为所有这些都可以使用IP很好地寻址

Sorry if this is very obvious. I'm new to GCE and have been googling all day trying to get this. I will paste my code below as well as the NGINX config but I don't think either are particularly helpful as all works fine addressing using the IP

index.js:

/* requirements */
var bodyParser = require("body-parser");
const WebSocket = require("ws");
const http = require("http");
const express = require("express");
const port = process.env.PORT || 3000;

/*
server definition and config
*/
const app = express();
app.use(bodyParser.json());
const server = http.createServer(app);

/*
web socket stuff
*/

const webSocketServer = new WebSocket.Server({
    server,
});

webSocketServer.on("connection", (webSocket) => {
    console.log("board trying to connect...");
    webSocket.on("message", (data) => {
        webSocketServer.clients.forEach((client) => {
            if (client === webSocket && client.readyState === WebSocket.OPEN) {
                client.send("[SERVER MESSAGE]: You are connected to the server :)");
            }
        });
    });
});

/*
activate server
*/
server.listen(port, () => {
    console.log(`Server is now running on port ${port}\n`);
});

nginx配置

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
        server_name _;

        location \ {
                # we're actually going to proxy all requests to
                # a Nodejs backend
                proxy_pass http://localhost:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                # I added this baby in
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}
server 
{
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name my_domain; # managed by Certbot
        location / {
                # we're actually going to proxy all requests to
                # a Nodejs backend
                proxy_pass http://localhost:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/my_domain/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/my_domain/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server 
{
    if ($host = my_domain) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
        listen 80 ;
        listen [::]:80 ;
    server_name my_domain;
    return 404; # managed by Certbot
}

非常感谢,如果这是一个菜鸟问题,我们深表歉意.负载均衡方面的新手

Thanks very much in advance and sorry if this is a noob question. Total noob when it comes to load balancing

推荐答案

已解决.经过更多的谷歌搜索后,我发现此主题的人大多数都面临相同的问题使用apache服务器或弹性beantalk,因此不使用nginx.

Solved. After a lot more googling I found this thread of people facing the same problem most either using apache servers or elastic beanstalk so not using nginx.

似乎很多人都通过Websocket来工作".使用socket.io,但它们并没有真正的双工连接,因为它可以回退到长时间轮询.

It seems that a lot of people get websockets to "work" using socket.io but they don't really have a duplex connection as it is falling back to long polling.

就我而言,答案很简单,我没有在我的nginx(facepalm)中包含服务器名称,并且我可能忘记了包含标头.现在,https转发看起来像这样(并且可以使用我的域进行寻址)

In my case the answer was simple, I didn't include the server name in my nginx (facepalm) and I may have forgot to include a header. The https forwarding now looks like this (and addressing using my domain works)

location / {
                # we're actually going to proxy all requests to
                # a Nodejs backend
                proxy_pass http://localhost:8080;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto $scheme;
                proxy_read_timeout  90;
              
              
        }

别忘了在更新后重新启动nginx

Don't forget to restart your nginx after you update

sudo systemctl restart nginx

这篇关于使用自定义域名在Google Compute Engine上进行Websocket连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆