Py学习  »  MongoDB

如何在Heroku中运行一个快速服务器来监听MongoDB和socket IO消息?

Aaron Waterman • 4 年前 • 286 次点击  

我正在为Heroku设置一个服务器后端,用于侦听Google OAAuthentication、侦听要保存到Mongo DB的消息,以及侦听使用Socket IO向所有连接的用户发送的聊天消息。

仅供参考,我的应用程序是使用react构建的。

在本地主机上运行时,我可以按预期运行这些功能,但我必须设置socket io使用的HTTP服务器实例和两个不同端口上所有其他功能使用的Express服务器。

但是,Heroku只给我一个端口。

我一直在网上寻找不同的解决方案。

我的最佳选择似乎是让socketIO通过同一个端口发送消息,但是当我这样做时,我会得到一个错误,说明我不能让两个不同的服务器访问同一个端口。

因此,即使我使用相同的express实例为socket io创建HTTP服务器实例,它们也被认为是单独的实例。

我的主要问题是,socket io需要一个HTTP服务器实例,并且其他所有功能都可以使用一个Express服务器来运行。

我想知道在部署到Heroku时是否有人遇到过这样的问题?我一直在四处寻找有类似问题的人,但没有任何运气。在这个问题上我真的可以使用一些指针。

我在下面发布服务器代码。

编辑2019年5月21日:我决定减少相关的代码,因为有很多与问题无关的代码需要解析。

require(`dotenv`).config();
require("./config/connection");

const express = require('express');
const app = express();

// Routes to Mongo DB
const chatRouter = require('./routes/chat');

// Passport
const passport = require("passport");
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const mongoose = require('mongoose');
const keys = require('./config/keys');

// socket io
const server = require('http').createServer(app);
const io = require('socket.io')(server);

// google
const routes = require("./routes");
const cookieSession = require('cookie-session');
const path = require('path');

const db = require('./model');

const PORT = process.env.PORT || 3001;

// Tells Express to Read the data sent in JSON format
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

// Tells Express to allows data to be sent across different origins
// required by CORS policy
app.use(function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

// Implementation of other features such as saving chat messages to database
// and implementing passport
...

// Chat implementation using Socket IO

io.on('connection', client => {

  // implementing chat feature
  ...

});

server.listen('8000', () => {
  console.log('listening on port 8000');
});

// alternatively we can attempt to listen on the port specified by Heroku
// server.listen(PORT, () => {
//   console.log(`listening on port ${PORT}`);
// });

// implementing more features, such as Google Oauth
// and other api routes
...

// Express application instance listening on port specified by Heroku
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});

我很感谢在这个问题上能给予的任何帮助。

谢谢您!

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38347
 
286 次点击  
文章 [ 1 ]  |  最新文章 4 年前
Aaron Waterman
Reply   •   1 楼
Aaron Waterman    4 年前

看来我的问题已经被问过了。

您可以在以下链接中找到答案, Socket.io + NodeJS doesn't work on Heroku

我只是简单的总结一下。

Heroku要求我们的应用程序在从前端到后端通信时在同一端口上运行API的所有功能,反之亦然。所以我第一次尝试指定两个不同的端口在本地工作,但在部署到Heroku时失败了。

然后我尝试对两个服务器实例使用相同的端口。


// implementing express
const express = require('express');
const app = express();

// uses port provided by Heroku OR port 3000
const PORT = process.env.PORT || 3000;

...

// implementing Socket IO
const server = require('http').createServer(app); // creates an instance of an http server
const io = require('socket.io')(server);

...

io.on('connection', client => {

    // server side chat features implemented here

}

server.listen(PORT); 

...

app.listen(PORT); // Express is returning a different instance of the http server

解决方案比我想象的要简单。

由于app.listen(port)返回HTTP服务器的一个实例,所以我们可以将其用于socket io。在单击之前,我必须先查看一些示例代码。全栈Web开发训练营的一位老师将我链接到这个Git Hub存储库,演示如何在将应用程序部署到Heroku时使用socket IO。

请参见以下链接, https://github.com/heroku-examples/node-socket.io/blob/master/server.js

上面示例中的实现看起来有点不同,但实际上正在执行与下面示例中演示的相同的操作,


// get Express library and create Express application
const express = require('express');
const app = express();

// get socket io library
const SocketIO = require('socket.io');

// uses port provided by Heroku OR port 3000
const PORT = process.env.PORT || 3000;

...

// This time we store the HTTP Server instance in a variable
// when we tell the Express application to listen on the specified port
const server = app.listen(PORT); 

// and use that instance to implement our socket io connection
const io = SocketIO.listen(server);

io.on('connection', client => {

    // server side chat features implemented here

}

希望这个解释能帮助别人理解和避免我面临的问题。

并且一定要查看发布的链接,因为我发现它们对于理解我所面临的问题以及如何解决它很有用。