1


我正在尝试使用 Express-generator 生成的项目来重现Socket.IO 官方网站中给出的“聊天示例”。我想保持生成的结构完整。我几乎将所有内容都与“聊天示例”保持一致,并尝试将其放入 Express-generator 生成的项目中。我遇到的问题是客户端无法调用脚本socket.io.js。在这里,我发布项目文件结构、已更改/添加的代码以及错误消息。
有人可以帮助我吗?非常感谢!

1. 项目文件结构(*:已更改;**:新增文件。)

ioChat (project name)
-- bin
   -- www (*)
-- node_modules
   -- socket.io 
   -- socket.io-adapter
   -- socket.io-client
   -- socket.io-parser
   -- (many other modules)
-- public
   -- images
   -- javascripts
   -- stylesheets
      -- style.css (*)
   -- index.html (**)
-- routes
   -- index.js (*)
   -- users.js
-- views
   -- error.jade
   -- index.jade
   -- layout.jade
-- app.js
-- package-lock.json
-- package.json


2. bin\www(注释//+++为添加代码)

#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('iochat:server');
var http = require('http');
var io = require('socket.io')(http); //++++


/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);


// socket io for realtime messaging  //++++
io.on("connection", function(socket){
    socket.on("chat", function(msgin){
        var msgout = { name: msgin.name, msg: msgin.msg , mtime: new Date()};
        io.emit("chat",msgout);
    });
});


/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}


3. public\index.html(新增)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>ioChat</title>
        <link rel="stylesheet" type="text/css" href="stylesheets/style.css">
        <script src="/socket.io/socket.io.js"></script>
        <!-- <script src="../node_modules/socket.io-client/dist/socket.io.js"></script> -->
        <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
        <script>
            $(function(){
                var socket = io();

                $("#btnSend").on("click",function(){
                    var msgout = {name:$("#senderName").val(), msg:$("#msg").val()};
                    socket.emit('chat',msgout);
                    $("#msg").val("");
                });

                socket.on("chat",function(msgin){
                    $("#msgList").append($("<li>").text(`${msgin.name} says: ${msgin.msg} (msgin.mtime)`));
                });

            });     
        </script>
    </head> 

    <body>
        <ul id="msgList"></ul>
        <div class="iptArea">
            <label for="name" class="msgItems">Name:</label>
            <input type="text" id="senderName"  class="msgItems"/
            <label for="msg"  class="msgItems">Message:</label>
            <input type="text" id="msg"  class="msgItems"/>
            <button class="msgItems" id="btnSend">Send</button>
        </div>
    </body>
</html>


4. routes\index.js(注释//+++是添加的代码)

var express = require('express');
var router = express.Router();

/* GET home page. Let http://localhost:3000 directly go to public\index.html*/
router.get('/'); //+++ 

module.exports = router;


5.服务器端报错信息(显然是404 not found):

GET /socket.io/socket.io.js 404 34.641 ms - 1142


6、客户端报错信息:

GET http://localhost:3000/socket.io/socket.io.js net::ERR_ABORTED 404 (Not Found)
Uncaught ReferenceError: io is not defined
4

2 回答 2

1

您可以使用 CDN 作为一种简单的方法,而不是从服务器获取文件。

查看:https ://cdnjs.com/libraries/socket.io

在你的public\index.html中使用它

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
于 2019-10-07T18:42:09.620 回答
0

经过长时间的搜索,我找到了我问题的最佳答案。请参考使用 express 生成器的简单 express socket.io 教程。

于 2019-10-29T14:57:32.553 回答