Home > Enterprise >  Socket is not defined other errors
Socket is not defined other errors

Time:12-09

Server side code:

const http = require("http");
const host = 'localhost';
const port = 8000;
const { Server } = require("socket.io");

// creating the server and starting it on port 8000
const server = http.createServer();
server.listen(port, host, () => {
    console.log(`Server is running on http://${host}:${port}`);
});
// making io object
const io = new Server(server);


// listening to connections to the server
io.on('connection', (socket) => {
    console.log('a user connected');
  });

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

// chat message coming to server

socket.on("details", (chatBundle) => {
    console.log(chatBundle);
});

Client side code:

<!DOCTYPE html>
<html>
    <body>
        <h1>CHAT ROOM</h1>
        <form onsubmit="return sendServer()">
            <label for="name">Name: 
                <input id="name" name="name" type="text">
            </label>
            
            <label for="text">Message: 
                <input id="text" name="text" type="text">
            </label>
            
            <input type="submit" id="send" >
        </form>
        <script src="/Users/chanson/node_modules/socket.io/client-dist/socket.io.js">
        </script>
        <script>
            function sendServer(){
                var sender = document.getElementById("name");
                var text = document.getElementById("text");
                var tempArray = [sender, text]
                socket.emit(chatmsg, tempArray)
            };
        </script>
        
    </body>
</html>

Aim: to make a chat messenger that would work on same computer browsers ports. e.g. Firefox port user can communicate to Chrome, Edge, Opera and Safari. (please don't ask why I have so many browsers).

CodePudding user response:

I don't like the way you import socket client please do something like

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

after that, you have to instantiate tour socket like:

const socket = io();
const text = document.getElementById("text")
socket.emit('chatMessage', text.value);

Make sure the event name is string ex here: chatMessage

CodePudding user response:

Client side errors (3)

  1. chatmsg has not been defined or given a value
  2. socket has not been created or assigned to a variable
  3. sendServer returns undefined, not false and hence will not prevent form submission when the submit button is pushed. (Calling event.preventDefault in the submit event is a more modern method of preventing submission).

A script element that addresses these considerations:

<script>
    const chatmsg = "details"; // added
    const socket = io(); // added
    function sendServer(){
        var sender = document.getElementById("name");
        var text = document.getElementById("text");
        var tempArray = [sender, text]
        socket.emit(chatmsg, tempArray)
    return false; // added
    };
</script>

Server side errors (several)

  1. No application.
    The client page must be served from the server in order to communicate with it using sockets - CORS errors are generated if the client page is loaded using the file:// protocol and then tries to communicate with the local host server using socket.io.

    1. A simple static express server can be set up to serve a request for http://localhost:8000/client.html.

    2. The server must also be capable of serving the socket.io client script using a suitable url in the src attribute of the client side script tag. A client tag used in testing was

      <script src="node_modules/socket.io-client/dist/socket.io.js"></script>
      

      but will depend on server directory structure and possibly the version of socket.io.js in use.

    The app is supplied as an argument when creating the http server.

  2. In the version of socketIO used for testing, requiring socket.io returns a function that is called to generate a socket server. Check documentation to verify that later versions return an export object with a Socket property. (See notes at bottom of answer)

  3. Socket message listening
    This is in the wrong place - server is an argument supplied to the io.on("connection", handler) handler function, and listening to socket events generated by the user who made the connection should be made in function scope of the connection handler.


Code used in testing

client.html

<!DOCTYPE html>
<html>
    <body>
        <h1>CHAT ROOM</h1>
        <form onsubmit="return sendServer()">
            <label for="name">Name: 
                <input id="name" name="name" type="text">
            </label>
            
            <label for="text">Message: 
                <input id="text" name="text" type="text">
            </label>
            
            <input type="submit" id="send" >
        </form>
        <!-- <script src="/Users/chanson/node_modules/socket.io/client-dist/socket.io.js"> -->
        <!-- particular to server setup: -->
        <script src="node_modules/socket.io-client/dist/socket.io.js"></script>
        <script>
            const chatmsg = "details";
            var socket = io();
            function sendServer(){
                var sender = document.getElementById("name");
                var text = document.getElementById("text");
                var tempArray = [sender, text]
                socket.emit(chatmsg, tempArray)
                return false;
            };
        </script>
        
    </body>
</html>

node script

const http = require("http");
const host = 'localhost';
const port = 8000;
 //** const { Server } = require("socket.io");
 //** 
    const express = require('express');
    const app = express();
    app.use(express.static('./'));
 const socketIO = require("socket.io");
 

// creating the server and starting it on port 8000
//**const server = http.createServer();
   const server = http.createServer(app);


server.listen(port, host, () => {
    console.log(`Server is running on http://${host}:${port}`);
});
// making io object

//**  const io = new Server(server);
    const io = socketIO(server, {cookie: false}); /* prevent io cookie - see https://github.com/socketio/socket.io/issues/2276 */


// listening to connections to the server
io.on('connection', (socket) => {
    console.log('a user connected');
    
//** move listening here, where socket is defined
    // chat message coming to server
    socket.on("details", (chatBundle) => {
           console.log(chatBundle);
    });
});

  • The version of socket.io used to prepare this answer was 2.2.0.

  • Version 4.x documentation confirms socket is still supplied to the connection handler.

  • Version 4.x doco shows Server as being imported from the socket.io package, which can't be done in CommonJS packages because the don't support the import statement.

  • AFAIK if in node you require an ECMA module package from within a CommonJS package, you are returned the default export of the ECMASScript module. You may need to investigate further if it is not the Server constructor function (or class object) exported in version 4.

  • You can import ECMAScript modules in CommonJS using the import function (not keyword), but the import operation is asynchronous. See How to use ES6 modules CommonJS for further details.

  • Related