带有Socket.io和Express的Node.js聊天应用程序在本地运行,但不在托管上

时间:2018-09-04 19:54:22

标签: node.js express socket.io

我制作了socket.io的“入门”示例,它在我的计算机上的localhost上运行良好。但是,当我将其上传到托管服务器时,它无法正常工作,客户端尝试获取socket.io.js时会抛出404错误:

<script src="/socket.io/socket.io.js"></script>

我用其他参考资料解决了这个问题(我不需要在localhost上做到这一点):

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>

但是,当客户端在主机上运行时,我不断收到404错误。似乎在托管时,Node.js服务器未在服务器上运行,而未运行servir socket.io文件。在本地主机上时,我没有收到这些404错误。有一个这样的调用示例:

GET http://localhost/socket.io/?EIO=3&transport=polling&t=MMc5E4X(在本地200可以正常工作)

GET http://tinatest.gearhostpreview.com/socket.io/?EIO=3&transport=polling&t=MMc5E4X(404)

我在免费的Node.js托管上获得了此示例,因此您可以查看一下,我在此服务器上激活了Node.js 8,并且该端口运行在端口80上:

http://tinatest.gearhostpreview.com/

服务器上的文件为:

Index.html

<!doctype html>
 <html>
 <head>
  <title>Socket.IO chat</title>
  <style>

  </style>
 </head>
 <body>
  <ul id="messages"></ul>
  <form action="">
    <input id="m" autocomplete="off" /><button>Send</button>
  </form>
 </body>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
 <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
 <script>
    $(function () {
    var socket = io();
    $('form').submit(function(){
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
   });
   socket.on('chat message', function(msg){
     $('#messages').append($('<li>').text(msg));
   });
 });
   </script>
 </html>

Index.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
 res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
    socket.on('chat message', function(msg){
      io.emit('chat message', msg);
    });
  });

http.listen(80, function(){
  console.log('listening on *:80');
});

package.json

{
 "name": "socket-chat-example",
 "version": "0.0.1",
 "description": "my first socket.io app",
 "dependencies": {
    "express": "^4.15.2",
    "socket.io": "^2.1.1",
    "socket.io-client": "^2.1.1"
 }
}

我希望有人可以帮助我完成这项工作,或者告诉我为什么不可行。如果您需要更多信息,请询问,我有另一台无法正常工作的生产服务器,我以为是关于该服务器上的Node的,但现在不是。

非常感谢。

2 个答案:

答案 0 :(得分:1)

考虑Node.js + express服务器的功能。在许多方面,它可以基于各种类型的http请求提供文件。但是,您必须准确告诉它要侦听的请求类型(GETPOST等)以及在什么路由上(//folder)。您甚至可以收听查询字符串,参数,帖子正文等。但是,由您来定义它们。

查看您的代码,您定义了什么路线?

仅一个:/,并且您允许GET到该路由的请求,并且作为响应,您正在服务index.html,这至少具有您所有的前端逻辑情况。

如果您尝试尝试GET条其他路线,例如/socket.io/,则默认情况下会收到404错误。

您提到的脚本文件具有src/socket.io,因为您没有提供服务socket.io代码的途径,所以它无法生产。

在localhost上,如果文件在同一项目中可用,则浏览器可以解析本地计算机上的相对路径。部署项目后,相对路径不再寻找您的计算机,而是用完整的URL击中路由器。希望这些文件可以提供。

您可以通过提供必要的socket.io代码的完整url引用来解决生产中的问题。

更多:示例:

index.js-查看下面的评论

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

/**
 * Your ROUTES
 * in production, when someone goes to http://tinatest.gearhostpreview.com/
 * they are calling your root route "/"
 * Your callback function is sending back index.html from your root directory
 * You add __dirname because you don't know where gearhost is actually putting
 * your stuff. 
 *
 * In production, you can only access server-side files if you serve them
 */
app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

/** 
 * ONE WAY TO SERVE JS TO YOUR CLIENT 
 * (there are many better ways of doing this)
 *
 * If you do this, you will not get a 404 error
 */
app.get('/socket.io/socket.io.js', function(req, res){
    // this assumes you have a folder within your root named socket.io 
    // and that it contains socket.io.js, 
    res.sendFile(__dirname + '/socket.io/socket.io.js');
})


io.on('connection', function(socket){
    socket.on('chat message', function(msg){
      io.emit('chat message', msg);
    });
});

http.listen(80, function(){
    console.log('listening on *:80');
});

index.html-仅查看脚本

<!-- 
    The src is the URI of an external script, that is, 
    a script external to this particular document.

    Below, the URIs are absolute paths for getting for files hosted by other services.
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>

<!-- 
    You can also use relative paths.

    If your src value is /socket.io, 
    then your page looks for a file
    relative to the current location of itself.

    On localhost, your page has access to files within its own folder
-->

<script src="/socket.io/socket.io.js"></script>

<!--
    HOWEVER, in production, you cannot use relative paths
    UNLESS you are serving your files either as static assets

    via middleware (http://expressjs.com/en/guide/using-middleware.html)
    OR via a public route (http://expressjs.com/en/4x/api.html#app.use)

    You are getting a 404 in production because you aren't serving
    assets.

    BUT!!! you can always use an external 3rd party service
-->

答案 1 :(得分:0)

由于我一直在思考问题,所以我没有运行任何节点服务器。我遵循了以下步骤,在我是在免费的非专用主机(没有远程桌面)上的情况下,我使用了VS Code:

  1. 将我的托管更改为Windows VPS(带有远程桌面)。
  2. 在那里安装node.js。
  3. 创建一个单独的socket.io服务器应用程序。
  4. 使用代码cmd在本地主机:8080中使用node index运行服务器。
  5. 从Windows控制面板安装iis。
  6. 创建指向服务器的单独客户端代码:VPS_IP_ADRESS:8080
  7. 构建客户端并将dist文件夹内容复制到IIS根文件夹(很可能是C:\inetpub\wwroot
  8. 运行IIS。

现在,一切都可以在任何设备的VPS IP中完美运行。我可以在设备之间聊天。我使用IIS作为客户端,因为我习惯在那里发布。我想我无法以任何方式在旧主机中执行此操作,因为我需要Node支持,而他们告诉我他们没有。 Ubuntu VPS应该是一个更便宜的选择,但这对我来说已经足够了。如果您有使用Node + Ubuntu服务器的经验,则应该尝试。

  • 我将在几个小时内用最终的生产代码(隐藏我的IP)来编辑这些代码