简体   繁体   English

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

[英]How do I deploy socket.io to Google App Engine?

I created my first node.js app using socket.io.我使用 socket.io 创建了我的第一个 node.js 应用程序。 Specifically I implemented the chat example published by socket.io.具体来说,我实现了 socket.io 发布的聊天示例 It works perfectly, locally.它在本地完美运行。 And then I tried deploying it to Google App Engine (making some code tweaks for node to work).然后我尝试将它部署到 Google App Engine(对 node 进行一些代码调整以使其正常工作)。

Everything shows up indicating that the node part is working well.一切都显示出来,表明节点部分运行良好。 However the chat doesn't work indicating that socket.io part isn't working.但是聊天不起作用,表明 socket.io 部分不起作用。 You can see the deployed app (and page source) here .您可以在此处查看已部署的应用程序(和页面源代码)。

Do I have to do anything additional?我还需要做些什么吗? Something in the yaml or json files? yaml 或 json 文件中的内容?

yaml content: yaml内容:

runtime: nodejs
vm: true

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

json content: 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"
  }
}

In short this cannot be done on production and it appears to be work in process .简而言之,这不能在生产中完成,而且似乎是在进行中 The right architecture is to have a chat server on google compute engine as outlined here .正确的架构是对谷歌计算引擎,聊天服务器概述这里

But as a proof of concept to use socket.io on google app engine is very similar to that shown in google appengine samples for websockets .但作为在 google 应用引擎上使用 socket.io 的概念证明,这与google appengine 示例中显示的 websockets非常相似。

In case of socket.io do the following steps on server side.如果是 socket.io,请在服务器端执行以下步骤。 Code snippet below.下面的代码片段。

  1. Create second express middleware and server.创建第二个快速中间件和服务器。
  2. Attach/use socket.io with new server.在新服务器上附加/使用 socket.io。
  3. Listen to port (65080).侦听端口 (65080)。
  4. Open firewall for port (65080) on google compute engine.在 google 计算引擎上为端口 (65080) 打开防火墙。
  5. Link to working repository .链接到工作存储库

socket.io changes on server side服务器端的 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);
      });
    });

open firewall by command通过命令打开防火墙

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

I hope Google comes up with a production-ready solution soon enough on as this will become a key armour in any PaaS-arsenal.我希望谷歌尽快提出一个生产就绪的解决方案,因为这将成为任何 PaaS 库中的关键盔甲。

Google has an example app using WebSockets here , you need to do the following to get it working correctly:谷歌在此处有一个使用 WebSockets 的示例应用程序,您需要执行以下操作才能使其正常工作:

  • Open up a firewall port for the server so clients can reach your server为服务器打开防火墙端口,以便客户端可以访问您的服务器
  • Fetch your internal IP in Google App Engine, so clients know what IP to connect to在 Google App Engine 中获取您的内部 IP,以便客户知道要连接到哪个 IP
  • Echo out your IP from your server via something like a rest API or a HTML page通过rest API或HTML页面之类的东西从你的服务器回显你的IP

That should be it (don't take my word for it though, this is what I've been able to find out after doing some research on the docs), hope it helps!应该是这样(尽管不要相信我的话,这是我在对文档进行了一些研究后能够找到的),希望它有所帮助!

Fetching your external IP from within Google App Engine从 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);
    });
}

Opening the firewall port打开防火墙端口

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

GAE support for persistent socket connections arrived in February 2019 ! GAE 对持久套接字连接的支持已于 2019 年 2 月推出

To make this work, you'll need to be using the flex environment and modify your app.yaml to include session_affinity :要完成这项工作,您需要使用flex环境并修改您的app.yaml以包含session_affinity

network:
  session_affinity: true

Note that I still had to open port 65080 to get this working, but no other changes were required for me.请注意,我仍然需要打开端口 65080 才能使其正常工作,但我不需要其他任何更改。

Read the deets at:阅读 deets:

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

This app.yaml configuration worked for me:这个 app.yaml 配置对我有用:

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

And I enabled the firewall rules by this command:我通过这个命令启用了防火墙规则:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM