1

I am trying to do a chat app from this link: https://socket.io/get-started/chat with the added functionality of able to send and display images in the chat but all i was able to do previously was to upload image. Currently, i am trying to use the stored image to send to the chat but was unable to do so.

index.html

<!DOCTYPE html>
<html>
  <head>
    <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: 3rem; 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; }

      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages > li { padding: 0.5rem 1rem; }
      #messages > li:nth-child(odd) { background: #efefef; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form id="form" action="">
      <input id="input" autocomplete="off" /><button>Send</button>
      <input type="file" id="upload-btn" name="filename"><input type="submit">
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();
      
        var messages = document.getElementById('messages');
        var form = document.getElementById('form');
        var input = document.getElementById('input');
      
        form.addEventListener('submit', function(e) {
          e.preventDefault();
          if (input.value) {
            socket.emit('chat message', input.value);
            input.value = '';
          }
        });
      
        socket.on('chat message', function(msg) {
          var item = document.createElement('li');
          item.textContent = msg;
          messages.appendChild(item);
          window.scrollTo(0, document.body.scrollHeight);
        });
        
        var ctx = document.getElementById('upload-btn').getContext('2d');

        // ...

        socket.on("image", function(info) {
          if (info.image) {
            var item = document.createElement('li');
            var img = new Image();
            messages.appendChild(item);
            window.scrollTo(0, document.body.scrollHeight);
            img.src = 'data:image/png;base64,' + info.buffer;
            ctx.drawImage(img, 0, 0);
          }
        });
      </script>
  </body>
</html>

index.js

var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
const http = require('http').Server(app);
const io = require('socket.io')(http);
const fs = require('fs'); // required for file serving



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

io.on('connection', (socket) => {
    console.log('a user connected');
    socket.on('disconnect', () => {
      console.log('user disconnected');
    });
  });

io.on('connection', (socket) => {
   socket.on('chat message', (msg) => {
   console.log('message: ' + msg);
    });
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' }); // This will emit the event to all connected sockets

io.on('connection', (socket) => {
    socket.broadcast.emit('hi');
});

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

io.on('connection', function(socket){
  fs.readFile(__dirname + '/images/image.jpg', function(err, buf){
    // it's possible to embed binary data
    // within arbitrarily-complex objects
    socket.emit('image', { image: true, buffer: buf.toString('base64') });
    console.log('image file is initialized');
  });
});

Penguin
  • 71
  • 1
  • 12
  • Does this answer your question? [socket io, node js, Simple example to send image/files from server to client](https://stackoverflow.com/questions/26331787/socket-io-node-js-simple-example-to-send-image-files-from-server-to-client) – ggorlen Mar 10 '21 at 03:20
  • @ggorlen i have tried that but it did not upload the image into the chat. maybe it is an html error ? – Penguin Mar 10 '21 at 03:29
  • `document.getElementById('upload-btn').getContext('2d');` doesn't make sense--`#upload-btn` is a button. This code should give you an error in the console explaining the problem, which is that `getContext` is not a function. Try using a canvas instead of a button to call `getContext("2d")` on. There may be other errors; it's best to be specific about what your particular problem/error is. – ggorlen Mar 10 '21 at 03:47
  • @ggorlen alright sorry for not being specific. – Penguin Mar 10 '21 at 03:54

1 Answers1

0
  1. With Server side

// Handle image
socket.on("sendImage", function(data){
    var guess = data.base64.match(/^data:image\/(png|jpeg);base64,/)[1];
    var ext = "";
    switch(guess) {
        case "png"  : ext = ".png"; break;
        case "jpeg" : ext = ".jpg"; break;
        default     : ext = ".bin"; break;
    }
    var savedFilename = "/uploads/" + randomString(10)+ext;
    fs.writeFile(__dirname + "/public" + savedFilename, getBase64Image(data.base64), 'base64', function(err) {
        if (err !== null)
            console.log(err);
        else 
            io.sockets.emit("receiveImage", {
                path: savedFilename,
            });
        console.log("Send image success!");
    });
});
  1. Client side

// Client receive
socket.on('receiveImage', function(data){
    // document.getElementById("showImage").src = data.path;
    var img = '<img id="showImage" src="' + data.path + '" width="100"/>';

    $('#show-message').append(img);
});

Sample code: https://downloadfree.top/nodejs-express-socketio-chat-message-and-send-image

  • 1
    You appear to be the author of the linked article. When linking to your own site or content (or content that you are affiliated with), you [must disclose your affiliation _in the answer_](/help/promotion) in order for it not to be considered spam. Having the same text in your username as the URL or mentioning it in your profile is not considered sufficient disclosure under Stack Exchange policy. – cigien May 08 '21 at 01:17