0

i want to make a chat app with react and socket.io i downloaded code from https://github.com/adrianhajdin/project_chat_application. I want to add upload file function using socketio_file_upload but when i upload the img. there is nothing happen..

this is my code

index.js (server)

const express = require('express');
const socketio = require('socket.io');
const http = require('http');
const siofu = require("socketio-file-upload");

const { addUser, removeUser, getUser, getUsersInRoom } = require('./users');

const PORT = process.env.PORT || 5000

const router = require('./router')

const app = express()
console.log(app,'------------------app----------')
const server = http.createServer(app)
const io = socketio(server)

io.on('connection', (socket)=>{
  const uploader = new siofu();
  uploader.dir = "/uploads";
  uploader.listen(socket);

  uploader.on("saved", function(event){
});

  uploader.on("error", function(event){
});

  
  socket.on('join', ({name, room}, callback)=>{
    const { user, error } = addUser({ id:socket.id, name, room })
    if(error) {
      return callback(error)
    }

    //admin system정보 여기서
    socket.emit('message', { user:'admin', text:`${user.name}, welcome to the room ${user.room}` })
    
    //braodcast는 room에 있는 모든 사람에게 msg를 보낸다.
    socket.broadcast.to(user.room).emit('message', { user: 'admin', text: `${user.name} has joined!` });

    socket.join(user.room)

    io.to(user.room).emit('roomData', {room: user.room, users: getUsersInRoom(user.room)})

    callback()
  })

  socket.on('sendMessage', (message, callback) => {
    const user = getUser(socket.id);

    io.to(user.room).emit('message', { user: user.name, text: message });
    io.to(user.room).emit('roomData', { room: user.room, users: getUsersInRoom(user.room)});

    callback();
  });

  socket.on('disconnect', () => {
    const user = removeUser(socket.id)
    io.to(user.room).emit('message', { user:'admin', text: `${user.name} has left`})
  })
})

app.use(siofu.router)

server.listen(PORT, ()=> console.log('---SERVER START---'))

Chat.jsx

import React, { useState, useEffect, useRef } from 'react';
import queryString from 'query-string'
import io from 'socket.io-client'



import './chat.css'
import InfoBar from '../InfoBar/InfoBar'
import Messages from '../Messages/Messages'
import Input from '../Input/Input'


let socket ='default'
const Chat = ({location}) => {
  const [name, setName] = useState('');
  const [room, setRoom] = useState('');
  const [message, setMessage] = useState('')
  const [messages, setMessages] = useState([])

  const END_POINT = 'localhost:5000'
  //componentdidmount와 같다
  useEffect(()=>{
    const {name, room} = queryString.parse(location.search)
    socket = io(END_POINT)
    setName(name)
    setRoom(room)

    //server에 join을 통해서 데이터를 보냄
    socket.emit('join', {name, room}, (res)=>{
    })
    //useEffect()애서 return 은 unmount와 같다. 즉 user leave일 때 사용!
    return () =>{
      socket.emit('disconnect')
      socket.off()
    }
  },[END_POINT, location.search])

  useEffect(() => {
  
    socket.on('message', (message) =>{
      setMessages([...messages, message])
    })
    // uploader.listenOnInput(document.getElementById("siofu_input"));
  }, [messages])

  const sendMessage = (event) => {
    event.preventDefault();

    if(message) {
      socket.emit('sendMessage', message, () => setMessage(''));
    }
  }
  
  return (
    <div className="outerContainer">
      <div className="container">
        <InfoBar room={room} />
        <Messages messages={messages} name={name} />
        <Input socket={socket} message={message} setMessage={setMessage} sendMessage={sendMessage} />
      </div>
    </div>
  );
};

export default Chat;

Input.jsx

import React, { Component } from 'react';
import SocketIOFileUpload from '../../../../server/node_modules/socketio-file-upload'

import './input.css';
class Input extends Component {


  uploadFile = (e) => {
    const {socket} = this.props
    console.log("uploading");
    // const files = e.target.files;
    const siofu = new SocketIOFileUpload(socket);
    siofu.listenOnInput(document.getElementById("siofu_input"));
  };
  render() {
    const { setMessage, sendMessage, message, socket } = this.props
    return (
      <form className="form">
        <input
          className="input"
          type="text"
          placeholder="Type a message..."
          value={message}
          onChange={({ target: { value } }) => setMessage(value)}
          onKeyPress={event => event.key === 'Enter' ? sendMessage(event) : null}
        />
        <input type="file" id="siofu_input" onChange={this.uploadFile.bind(this)}/>
        <button className="sendButton" onClick={e => sendMessage(e)}>Send</button>
      </form>
    );
  }
}

export default Input;

users.js

const users = [];

const addUser = ({ id, name, room }) => {
  name = name.trim().toLowerCase();
  room = room.trim().toLowerCase();

  const existingUser = users.find((user) => user.room === room && user.name === name);

  if(!name || !room) return { error: 'Username and room are required.' };
  if(existingUser) return { error: 'Username is taken.' };

  const user = { id, name, room };

  users.push(user);

  return { user };
}

const removeUser = (id) => {
  const index = users.findIndex((user) => user.id === id);

  if(index !== -1) return users.splice(index, 1)[0];
}

const getUser = (id) => users.find((user) => user.id === id);

const getUsersInRoom = (room) => users.filter((user) => user.room === room);

module.exports = { addUser, removeUser, getUser, getUsersInRoom };

How can i upload img file to chat app....

Isaac
  • 1
  • 3
  • Does this answer your question? [Can I upload a file to server by socket.io in node.js?](https://stackoverflow.com/questions/5973825/can-i-upload-a-file-to-server-by-socket-io-in-node-js) – BENARD Patrick Aug 01 '20 at 06:39

1 Answers1

0

At first, you must create "uploads" folder to upload files. When I run the app on local, I created folder on to D drive and changed uploader.dir from '/uploads' to "uploads";

At second, when you select DOM, you used document.elementById, this is wrong, must use ref={(el)=>this.variable=el} and change to siofu.listenOnInput(this.variable);

At third, you did define upload logic in onChange event listener, have to define in componentDidMount().