如何将socket.io部署到Google App Engine?

时间:2016-05-23 21:59:12

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

我使用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"
  }
}

4 个答案:

答案 0 :(得分:9)

简而言之,这不能在制作中完成,而且似乎是work in process。正确的架构是按照here概述在谷歌计算引擎上安装聊天服务器。

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

如果是socket.io,请在服务器端执行以下步骤。下面的代码片段。

  1. 创建第二个快速中间件和服务器。
  2. 使用新服务器附加/使用socket.io。
  3. 收听端口(65080)。
  4. 在谷歌计算引擎上打开端口防火墙(65080)。
  5. 链接到working repository
  6. 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-arsenal的关键装备。

答案 1 :(得分:6)

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

  • 为服务器打开防火墙端口,以便客户端可以访问您的服务器
  • 在Google App Engine中获取内部IP,以便客户知道要连接的IP
  • 通过类似其他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"

答案 2 :(得分:1)

GAE对持久套接字连接的支持在February 2019中出现了!

要执行此操作,您需要使用flex环境并修改app.yaml使其包含session_affinity

network:
  session_affinity: true

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

在以下位置阅读说明

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

答案 3 :(得分:0)

这个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"