简体   繁体   中英

NodeJS Cannot find module 'io' ( socket.io with express 4.15.3)

I am new in NodeJS. I am trying to run simple chat application with express and socket.io module, but when I run application, on the page where I am using socket, on console I am getting this error, and can't understand the problem. on web page I am getting this (see attached image)

Error: Cannot find module 'io'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at new View (/Applications/XAMPP/xamppfiles/htdocs/NODE/express/node_modules/express/lib/view.js:80:30)

在此处输入图片说明

Actually I have found this example in internet ( https://github.com/socketio/socket.io/tree/master/examples/chat ), and try to join it to my project.For view I am using EJS. All my JS and css files in public directory, I have copied socket.io.js from node_modules/socket.io-client/dist/socket.io.js to my javascript directory. Here is my code.

app.js

let express = require('express');
let bodyParser = require('body-parser');
let path = require('path');
let expressValidator = require('express-validator');
let db = require('mysql');
let sessions = require('express-session');

let session;

let app = express();

let connection = db.createConnection({
    host:"localhost",
    user:'root',
    password:'',
    database:'oulala'
});

connection.connect((error)=>{
    if(error){
        console.log('Error')
    }else{
        console.log("connected");
    }
});

//Body parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(sessions({
    secret:'$%2878asd8783yuh3b129x831726375r367*&^%$#',
    resave:false,
    saveUninitialized:true
}))

//View engine
app.set('view engine','ejs');
app.set('views',path.join(__dirname,'views'));

app.use(express.static(__dirname + '/public'));

//Global Vars

app.use((req,res,next)=>{
    res.locals.errors = null;
    res.locals.isAuthenticated = false;
    next();
});

app.use(expressValidator({
    errorFormatter: (param,msg,value)=>{
        let namespace = param.split('.')
        , root = namespace.shift()
        , formParam = root;

        while(namespace.length){
            formParam+= '['+namespace.shift()+']';
        }
        return {
            param : formParam,
            msg   : msg,
            value : value
        }

    }
}));

app.get('/logout',(req,res)=>{
    req.session.destroy((error)=>{
        res.redirect('/');
    })
})

app.post('/login',(req,res) => {
    session = req.session;
    req.checkBody('username','Username is required').notEmpty();
    req.checkBody('password','Password is required').notEmpty();
    errors = req.validationErrors();
    if ( errors ) {
        res.render('login',{
            title:"Login",
            errors:errors
        });
    }else{
        if(req.body.username == 'admin' && req.body.password == 'admin'){
            session.uniqueID = req.body.username;
            isAuthenticated = true;
        }
        res.redirect('/');
    }
})


app.get('/:page?',(req,res) => {
    //res.send('Hello first page');
    //res.json(people);

    let page = req.params.page;
    if ( page ) {
        if ( page == 'posts' ){
            connection.query("SELECT * FROM members",(error,rows,fields)=>{
                if(error){
                    connection.release();
                    console.log('Error in the query - '+error);

                }else{
                    res.render(page,{
                        title:page,
                        users:rows
                    });
                }
            });

        }else{
            res.render(page,{
                title:page,
                user:authenticate
            });
        }

    }else{


        session = req.session;
        if(session.uniqueID){
            res.render('index',{
                title:"Index",
                user:authenticate
            });
        }else{
            res.render('login',{
                title:"Login",
                user:authenticate
            });
        }
    }

});

// get form submition, post request
app.post('/users/add',(req,res) => {
    //console.log(req.body.first_name); // req.body - request object

    req.checkBody('first_name','Fisrtname is required').notEmpty();
    req.checkBody('last_name','Lastname is required').notEmpty();
    req.checkBody('email','Email is required').notEmpty();
    errors = req.validationErrors();

    if ( errors ) {
        res.render('index',{
            title:"Customers",
            users:people,
            errors:errors
        });
    }else{
        var newUser = {
            first_name:req.body.first_name,
            last_name:req.body.last_name,
            email:req.body.email
        }

        people.push(newUser);

        res.render(page,{
            title:page,
            users:people,
            user:authenticate
        });
    }

});

app.listen(3000, () => {
    console.log('server started on port 3000....');
});

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

// Chatroom

var numUsers = 0;

io.on('connection', function (socket) {
  var addedUser = false;

  // when the client emits 'new message', this listens and executes
  socket.on('new message', function (data) {
    // we tell the client to execute 'new message'
    socket.broadcast.emit('new message', {
      username: socket.username,
      message: data
    });
  });

  // when the client emits 'add user', this listens and executes
  socket.on('add user', function (username) {
    if (addedUser) return;

    // we store the username in the socket session for this client
    socket.username = username;
    ++numUsers;
    addedUser = true;
    socket.emit('login', {
      numUsers: numUsers
    });
    // echo globally (all clients) that a person has connected
    socket.broadcast.emit('user joined', {
      username: socket.username,
      numUsers: numUsers
    });
  });

  // when the client emits 'typing', we broadcast it to others
  socket.on('typing', function () {
    socket.broadcast.emit('typing', {
      username: socket.username
    });
  });

  // when the client emits 'stop typing', we broadcast it to others
  socket.on('stop typing', function () {
    socket.broadcast.emit('stop typing', {
      username: socket.username
    });
  });

  // when the user disconnects.. perform this
  socket.on('disconnect', function () {
    if (addedUser) {
      --numUsers;

      // echo globally that this client has left
      socket.broadcast.emit('user left', {
        username: socket.username,
        numUsers: numUsers
      });
    }
  });
});

client.js

$(function() {
  var FADE_TIME = 150; // ms
  var TYPING_TIMER_LENGTH = 400; // ms
  var COLORS = [
    '#e21400', '#91580f', '#f8a700', '#f78b00',
    '#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
    '#3b88eb', '#3824aa', '#a700ff', '#d300e7'
  ];

  // Initialize variables
  var $window = $(window);
  var $usernameInput = $('.usernameInput'); // Input for username
  var $messages = $('.messages'); // Messages area
  var $inputMessage = $('.inputMessage'); // Input message input box

  var $loginPage = $('.login.page'); // The login page
  var $chatPage = $('.chat.page'); // The chatroom page

  // Prompt for setting a username
  var username;
  var connected = false;
  var typing = false;
  var lastTypingTime;
  var $currentInput = $usernameInput.focus();

  var socket = io();

  function addParticipantsMessage (data) {
    var message = '';
    if (data.numUsers === 1) {
      message += "there's 1 participant";
    } else {
      message += "there are " + data.numUsers + " participants";
    }
    log(message);
  }

  // Sets the client's username
  function setUsername () {
    username = cleanInput($usernameInput.val().trim());

    // If the username is valid
    if (username) {
      $loginPage.fadeOut();
      $chatPage.show();
      $loginPage.off('click');
      $currentInput = $inputMessage.focus();

      // Tell the server your username
      socket.emit('add user', username);
    }
  }

  // Sends a chat message
  function sendMessage () {
    var message = $inputMessage.val();
    // Prevent markup from being injected into the message
    message = cleanInput(message);
    // if there is a non-empty message and a socket connection
    if (message && connected) {
      $inputMessage.val('');
      addChatMessage({
        username: username,
        message: message
      });
      // tell server to execute 'new message' and send along one parameter
      socket.emit('new message', message);
    }
  }

  // Log a message
  function log (message, options) {
    var $el = $('<li>').addClass('log').text(message);
    addMessageElement($el, options);
  }

  // Adds the visual chat message to the message list
  function addChatMessage (data, options) {
    // Don't fade the message in if there is an 'X was typing'
    var $typingMessages = getTypingMessages(data);
    options = options || {};
    if ($typingMessages.length !== 0) {
      options.fade = false;
      $typingMessages.remove();
    }

    var $usernameDiv = $('<span class="username"/>')
      .text(data.username)
      .css('color', getUsernameColor(data.username));
    var $messageBodyDiv = $('<span class="messageBody">')
      .text(data.message);

    var typingClass = data.typing ? 'typing' : '';
    var $messageDiv = $('<li class="message"/>')
      .data('username', data.username)
      .addClass(typingClass)
      .append($usernameDiv, $messageBodyDiv);

    addMessageElement($messageDiv, options);
  }

  // Adds the visual chat typing message
  function addChatTyping (data) {
    data.typing = true;
    data.message = 'is typing';
    addChatMessage(data);
  }

  // Removes the visual chat typing message
  function removeChatTyping (data) {
    getTypingMessages(data).fadeOut(function () {
      $(this).remove();
    });
  }

  // Adds a message element to the messages and scrolls to the bottom
  // el - The element to add as a message
  // options.fade - If the element should fade-in (default = true)
  // options.prepend - If the element should prepend
  //   all other messages (default = false)
  function addMessageElement (el, options) {
    var $el = $(el);

    // Setup default options
    if (!options) {
      options = {};
    }
    if (typeof options.fade === 'undefined') {
      options.fade = true;
    }
    if (typeof options.prepend === 'undefined') {
      options.prepend = false;
    }

    // Apply options
    if (options.fade) {
      $el.hide().fadeIn(FADE_TIME);
    }
    if (options.prepend) {
      $messages.prepend($el);
    } else {
      $messages.append($el);
    }
    $messages[0].scrollTop = $messages[0].scrollHeight;
  }

  // Prevents input from having injected markup
  function cleanInput (input) {
    return $('<div/>').text(input).text();
  }

  // Updates the typing event
  function updateTyping () {
    if (connected) {
      if (!typing) {
        typing = true;
        socket.emit('typing');
      }
      lastTypingTime = (new Date()).getTime();

      setTimeout(function () {
        var typingTimer = (new Date()).getTime();
        var timeDiff = typingTimer - lastTypingTime;
        if (timeDiff >= TYPING_TIMER_LENGTH && typing) {
          socket.emit('stop typing');
          typing = false;
        }
      }, TYPING_TIMER_LENGTH);
    }
  }

  // Gets the 'X is typing' messages of a user
  function getTypingMessages (data) {
    return $('.typing.message').filter(function (i) {
      return $(this).data('username') === data.username;
    });
  }

  // Gets the color of a username through our hash function
  function getUsernameColor (username) {
    // Compute hash code
    var hash = 7;
    for (var i = 0; i < username.length; i++) {
       hash = username.charCodeAt(i) + (hash << 5) - hash;
    }
    // Calculate color
    var index = Math.abs(hash % COLORS.length);
    return COLORS[index];
  }

  // Keyboard events

  $window.keydown(function (event) {
    // Auto-focus the current input when a key is typed
    if (!(event.ctrlKey || event.metaKey || event.altKey)) {
      $currentInput.focus();
    }
    // When the client hits ENTER on their keyboard
    if (event.which === 13) {
      if (username) {
        sendMessage();
        socket.emit('stop typing');
        typing = false;
      } else {
        setUsername();
      }
    }
  });

  $inputMessage.on('input', function() {
    updateTyping();
  });

  // Click events

  // Focus input when clicking anywhere on login page
  $loginPage.click(function () {
    $currentInput.focus();
  });

  // Focus input when clicking on the message input's border
  $inputMessage.click(function () {
    $inputMessage.focus();
  });

  // Socket events

  // Whenever the server emits 'login', log the login message
  socket.on('login', function (data) {
    connected = true;
    // Display the welcome message
    var message = "Welcome to Socket.IO Chat – ";
    log(message, {
      prepend: true
    });
    addParticipantsMessage(data);
  });

  // Whenever the server emits 'new message', update the chat body
  socket.on('new message', function (data) {
    addChatMessage(data);
  });

  // Whenever the server emits 'user joined', log it in the chat body
  socket.on('user joined', function (data) {
    log(data.username + ' joined');
    addParticipantsMessage(data);
  });

  // Whenever the server emits 'user left', log it in the chat body
  socket.on('user left', function (data) {
    log(data.username + ' left');
    addParticipantsMessage(data);
    removeChatTyping(data);
  });

  // Whenever the server emits 'typing', show the typing message
  socket.on('typing', function (data) {
    addChatTyping(data);
  });

  // Whenever the server emits 'stop typing', kill the typing message
  socket.on('stop typing', function (data) {
    removeChatTyping(data);
  });

  socket.on('disconnect', function () {
    log('you have been disconnected');
  });

  socket.on('reconnect', function () {
    log('you have been reconnected');
    if (username) {
      socket.emit('add user', username);
    }
  });

  socket.on('reconnect_error', function () {
    log('attempt to reconnect has failed');
  });

});

index.ejs

<% include partials/header %>
    <h1><%= title %></h1>
    <ul class="pages">
    <li class="chat page">
      <div class="chatArea">
        <ul class="messages"></ul>
      </div>
      <input class="inputMessage" placeholder="Type here..."/>
    </li>
    <li class="login page">
      <div class="form">
        <h3 class="title">What's your nickname?</h3>
        <input class="usernameInput" type="text" maxlength="14" />
      </div>
    </li>
  </ul>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="/javascript/socket.io.js"></script>
    <script src="/javascript/client.js"></script>
<% include partials/footer %>

package.json

{
  "name": "customerapp",
  "version": "1.0.0",
  "description": "Simple customer managment app",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Anna Gabrielyan",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.17.2",
    "ejs": "^2.5.6",
    "express": "^4.15.3",
    "express-session": "^1.15.3",
    "express-validator": "^3.2.0",
    "mysql": "^3.10.10",
    "oauth2-server": "^2.4.1",
    "socket.io": "^2.0.2"
  }
}

First you need to install packages using below command

npm install

This command will install all the packages from your package.json once done you can run this program.

did you install socket.io using npm. if not try

npm install --save socket.io

can you show me package.json,?

I find my bug. I removed this code

app.listen(3000, () => {
    console.log('server started on port 3000....');
});

and added this

server.listen(3000);

after this

var server = require('http').createServer(app);
var io = require('socket.io').listen(server);

thanks to @Curious for helping and great answer socket.io - can't get it to work, having 404's on some kind of polling call

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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