【问题标题】:How do I deploy socket.io to Google App Engine?如何将 socket.io 部署到 Google App Engine?
【发布时间】:2016-09-20 22:33:03
【问题描述】:

我使用 socket.io 创建了我的第一个 node.js 应用程序。具体来说,我实现了socket.io发布的chat example。它在本地完美运行。然后我尝试将其部署到 Google App Engine(对节点进行一些代码调整以使其正常工作)。

一切都表明节点部分运行良好。但是聊天不起作用,表明 socket.io 部分不起作用。您可以看到已部署的应用程序(和页面源)here

我是否需要做任何额外的事情? yaml 或 json 文件中的内容?

yaml 内容:

runtime: nodejs
vm: true

skip_files:
  - ^(.*/)?.*/node_modules/.*$

json 内容:

{
  "name": "Chaty",
  "description": "chatrooms app",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "McChatface",
  "engines": {
    "node": "~4.2"
  },
  "scripts": {
    "start": "node app.js",
    "monitor": "nodemon app.js",
    "deploy": "gcloud preview app deploy"
  },
  "dependencies": {
    "express": "^4.13.4",
    "socket.io": "^1.4.6"
  }
}

【问题讨论】:

    标签: node.js google-app-engine socket.io google-cloud-platform


    【解决方案1】:

    简而言之,这不能在生产中完成,它似乎是work in process。正确的架构是在谷歌计算引擎上拥有一个聊天服务器,如here 所述。

    但作为概念证明,在谷歌应用引擎上使用 socket.io 与google appengine samples for websockets 中显示的非常相似。

    如果是 socket.io,请在服务器端执行以下步骤。下面是代码 sn-p。

    1. 创建第二个 express 中间件和服务器。
    2. 在新服务器上附加/使用 socket.io。
    3. 监听端口 (65080)。
    4. 为谷歌计算引擎上的端口 (65080) 打开防火墙。
    5. 链接到working repository

    socket.io 在服务器端发生变化

        var app_chat = require('express')();
        var server1 = require('http').Server(app_chat);
        var io = require('socket.io')(server1);
        server1.listen(65080);
    
        io.on('connection', function (socket) {
          console.log('user connected');
          socket.on('chat_message', function (data) {
            console.log('client sent:',data);
            socket.emit('chat_message', 'Server is echoing your message: ' + data);
          });
        });
    

    通过命令打开防火墙

    gcloud compute firewall-rules create default-allow-websockets \
        --allow tcp:65080 \
        --target-tags websocket \
        --description "Allow websocket traffic on port 65080"
    

    我希望 Google 能尽快推出可用于生产的解决方案,因为这将成为任何 PaaS 武器库的关键装甲。

    【讨论】:

    【解决方案2】:

    February 2019 中的 GAE 支持持续套接字连接!

    要完成这项工作,您需要使用flex 环境并修改您的app.yaml 以包含session_affinity

    network:
      session_affinity: true
    

    请注意,我仍然需要打开端口 65080 才能使其正常工作,但我不需要进行其他更改。

    阅读详情:

    https://cloud.google.com/appengine/docs/flexible/nodejs/using-websockets-and-session-affinity

    【讨论】:

    • 您在移动设备上有什么问题吗?在桌面上一切正常,但在我的 iPhone(safari 和 chrome)上却无法连接。此外,我还没有打开任何其他端口......一切都通过8080。最后,我的应用程序正在使用我准备好的https可能会导致问题......我在这里难住了。
    • 我在移动设备上仍然遇到问题。我尝试让它与 https 一起工作,但似乎 chrome 只是不接受证书。甚至 Safari 也可以工作,同样的引擎! @tommyc38:你有想过吗?我将尝试将我的后端移至 AWS。
    【解决方案3】:

    Google 有一个使用 WebSockets here 的示例应用程序,您需要执行以下操作才能使其正常工作:

    • 为服务器打开防火墙端口,以便客户端可以访问您的服务器
    • 在 Google App Engine 中获取您的内部 IP,以便客户端知道要连接到哪个 IP
    • 通过诸如 REST API 或 HTML 页面之类的方式从服务器中回显您的 IP

    应该就是这样(不过不要相信我的话,这是我在对文档进行一些研究后能够找到的),希望对您有所帮助!

    从 Google App Engine 中获取您的外部 IP

    var METADATA_NETWORK_INTERFACE_URL = 'http://metadata/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip';
    
    function getExternalIp (cb) {
        var options = {
            url: METADATA_NETWORK_INTERFACE_URL,
            headers: {
                'Metadata-Flavor': 'Google'
            }
        };
    
        request(options, function (err, resp, body) {
            if (err || resp.statusCode !== 200) {
                console.log('Error while talking to metadata server, assuming localhost');
                return cb('localhost');
            }
    
            return cb(body);
        });
    }
    

    打开防火墙端口

    gcloud compute firewall-rules create default-allow-websockets \
        --allow tcp:65080 \
        --target-tags websocket \
        --description "Allow websocket traffic on port 65080"
    

    【讨论】:

    • 我觉得我已经很接近了,但还没有开始工作。我打开了防火墙端口并部署了 google websocket 项目。那行得通。但我还不知道如何使它与 socket.io 一起工作。因为socket.io使用的是使用8080监听的服务器并使用express。 // 启动服务器 var server = app.listen(process.env.PORT || '8080', '0.0.0.0', function() { console.log('Press Ctrl+C to quit.'); }) ; var io = require('socket.io')(server);
    • 示例应用的链接已损坏;这个似乎很接近:github.com/GoogleCloudPlatform/appengine-websocketchat-java
    【解决方案4】:

    这个 app.yaml 配置对我有用:

    runtime: nodejs
    env: flex
    manual_scaling:
    instances: 1
    network:
     session_affinity: true
    

    我通过这个命令启用了防火墙规则:

    gcloud compute firewall-rules create default-allow-websockets     --allow 
    tcp:65080     --target-tags websocket     --description "Allow websocket 
    traffic on port 65080"
    

    【讨论】:

    • 这对我有用。对于我的应用引擎实例,只有 yaml 配置就足够了,不需要更改防火墙设置
    猜你喜欢
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 2015-02-19
    • 2017-09-29
    • 1970-01-01
    • 2022-12-14
    • 2020-05-06
    • 2017-07-27
    相关资源
    最近更新 更多