0

I am attempting to create a chat app using socket.io on nodeJS and I want to add image transmission using the method outlined here

I'm running into an issue where if the image file is any larger than ~1MB, it seems to reset the connection and the io connection event is raised again (as the chat log gets re-sent).

Here is my code: CLIENTSIDE

<html>
    <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <title>Socket.IO chat</title>
    <style>
      body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }

      #form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 5rem; box-sizing: border-box; backdrop-filter: blur(10px); }
      #input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
      #input:focus { outline: none; }
      #form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
      #subBtn {background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; margin-bottom:5.3rem;bottom: 0; left: 200; right: 0; display: flex; height: 2rem; box-sizing: border-box; backdrop-filter: blur(10px);}
      #img {background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; margin-bottom:5.3rem;bottom: 0; left: 200; right: 0; display: flex; height: 2rem; box-sizing: border-box; backdrop-filter: blur(10px);}
      #nametag {background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed;margin-top:-0.05rem;top: 0; left: 0; right: 0; display: flex; height: 2rem; box-sizing: border-box; backdrop-filter: blur(10px);}
        
      #messages { list-style-type: none; margin-bottom: 2rem; padding: 0; }
      #messages > li { padding: 1rem 1rem; font-size:30px; }
      #messages > li:nth-child(odd) { background: #efefef; }
    </style>
  </head>
  <body> 
     
  <div id="loginPrompt" style="position:fixed; margin:0;margin-top:-1rem; background-color:blue;width:100%;height:100%;z-index:2;">
        <h2 style="color:white;margin-left:0.2rem;">Enter your name: </h2>
        <form id="formName" style="margin-left:0.2rem;">
            <input id="inputName"><button>Submit</button>
            </form>
        </div>
        
        <div id="imageDiv" style="position:absolute; margin-bottom:5rem; z-index:2;"></div>
    
    <ul id="messages"></ul>
    <form id="form" action="">
        <input id="input" autocomplete="off"  placeholder="Enter your message..."/><button>Send</button>
    </form> 
    
    <input type="file" id="img" onchange="setImgSrc(this)" accept="image/*"/>
<input type="submit" id="subBtn" onclick="submitImg()"/> 

    <script src="/socket.io/socket.io.js"></script>
    <p id="nametag"></p>
    
    
     
    
    
    <script>

  var socket = io.connect()
  
  var src

  var setImgSrc = (elm) => {
    var fr = new FileReader()
    fr.onload = () => (src = fr.result)
    fr.readAsArrayBuffer(elm.files[0])
  }
  
  var submitImg = () => socket.emit('submitImg',src)

  socket.on('sentImg', (src) => {
   // Create Img...
    var img = document.createElement('img')
    img.src = (window.URL || window.webkitURL).createObjectURL(
      new Blob([src], {
        type: 'image/png'
      })
    ) 
    img.width = 300
    img.height = 300
    //sleep(5000)
    var theDiv = document.createElement('div')
    theDiv.append(img)
    document.getElementById('messages').append(theDiv)
    

   //var usern = document.getElementById('nametag')
  //socket.emit('chat message', "(Photo from " + usern.innerHTML + ")")
   
  })


      var username = ""; //prompt("Please enter a username: ", "");
      var messages = document.getElementById('messages');
      var form = document.getElementById('form');
      var input = document.getElementById('input');
      var formName = document.getElementById('formName');
      var inputName = document.getElementById('inputName');

      formName.addEventListener('submit', function (k) {
      k.preventDefault();
      if (inputName.value)
      {
      username = inputName.value;
      nametag.innerHTML = username;
      $('#loginPrompt').hide();
      $('#form').attr('style', '');
      //form.width = "100%";
      socket.emit('chat message', username + ' has joined!');
      
      form.addEventListener('submit', function(e) {
        e.preventDefault();
        if (input.value) {
          socket.emit('chat message', username + ': ' + input.value);
          input.value = "";
          $('#input').attr('placeholder', 'Enter your message...');
        }
        if (inputName.value != "Enter your name..."){
          name = inputName.value;
        }
      });
      
      
      //return false;
      }
      });

      
      

      socket.on('chat message', function(msg) {
        var item = document.createElement('li');
        item.textContent = msg;
        messages.appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      }); 
      
      
      
    </script>
    
  </body>
</html>

SERVERSIDE JS:

const http = require('http').Server(app);
const io = require('socket.io')(http);
const port = process.env.PORT || 3001;
var chatlog = [];


app.use((req, res, next) => {
  res.set('Cache-Control', 'no-store')
  next()
})

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

io.on('connection', (socket) => {
    for (i = 0; i < chatlog.length; i++){
    io.emit('chat message', chatlog[i]);
    }
  socket.on('chat message', msg => {
    chatlog.push(msg);
  io.emit('chat message', msg); 
  });
  socket.on('submitImg', (src) => {
    console.log('Client sent image')

    //Client submit an image
    io.emit('sentImg', src) //the server send the image src to all clients
  });
});

http.listen(port, () => {
  console.log(`Socket.IO server running at http://localhost:${port}/`);
});

When I try to append the image to any element, if the file is small enough it'll work, if not, it'll just re-send the chat log as though a complete reconnect occurred.

I'm assuming the issue is that the data stream upload for the photo is not happening fast enough, and other code is executing prematurely. I employed a wait function and threw a whopping 5s delay in, but I still had the same issue. What's worse is the wait would only actually fire on the filesizes that would've worked anyway.

Any help would be greatly appreciated!!

Tyris
  • 1
  • 1

1 Answers1

0

I found the answer.

I simply need to change the max buffer filesizes as described in socket.io disconnects due to the size of data

Tyris
  • 1
  • 1