이것저것

socket.io 본문

카테고리 없음

socket.io

곰태태 2020. 8. 3. 18:47
반응형
SMALL

client-io 선언 위치

해결법 : 아래와 같이 컴포넌트의 밖에 선언을 해준 뒤 사용해주면 되는 거였다.

import React, { useEffect, useState } from 'react';
import io from "socket.io-client"

let server = "http://localhost:3002/api"
let socket = io(server);

const Chat = () => { ...

 

이제 이 부분은 해결되었으니 이벤트를 만들고 받아오는걸 해보자

현재 이벤트를 보내고 받는 부분이 안되고 있다.

 

해결 : socket.io에서 주소를 /api 를 붙여서 보냈기 때문이다. (이유는 모름 하면서 잡을 것)

 


그냥 emit은 나를 포함한 대상에게 메시지를 보내고,

broadcast.emit은 나를 제외한 대상에게 메시지를 보내는 메소드이다.

object는 보내는 데이터로, 받는쪽에서는 함수에 데이터를 인수로 받아서 조작하게 된다.

만약에 emit에 인수를 두개 보내면, 콜백함수에서 두개의 인수로 나누어 받을 수 있다.

socket.emit(event, object)

socket.broadcast.emit(event, object)

 

event는 문자열로, "chat" 으로 보낸 메시지는 io.on("chat", function) 또는 socket.on("chat", function) 가 받게된다.

 

받는쪽의 두번째 인수인 function에서는 인수로 msg,data등의 이름으로(이건 알아서 정하면된다) 받아서 다시 보내주거나 조작하거나 DB에 저장할 수 있다.

주로 io는 connection으로 받고, 그 인수로 socket을 생성해서 그안에서 socket을 이용해 요청을 받는것으로 보인다.

 

 서버측을 정리하자면 다음과 같다.

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const cors = require('cors')
const bodyParser = require('body-parser');
const api = require('./router/index');
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use('/api', api);
/*-----------------------------------------------------*/
io.on('connection', socket=>{
  console.log("new client connected");

  socket.broadcast.emit('msg', '새 유저가 들어왔습니다');
  
  socket.on('msg', (chatMessage)=>{
      console.log('msg : ' +chatMessage);
      socket.emit('msg', chatMessage);
  })

  socket.on('disconnect', ()=>{
      console.log("client disconnected");
      socket.broadcast.emit('msg', '유저가 떠났습니다');
  })
})
/*-----------------------------------------------------*/
const port = 3002;
server.listen(port, ()=>{
  console.log(`http://localhost:${port}/api`);
})

broadcast.emit은 상대에게만 보내고, 그냥 socket.emit을 할 때는 상대에게 보내지지 않았다. (본인한테만 보임)

 

여기서 io.emit으로 변경하자 정상적으로 메시지가 전송되었다.

정리하면, socket.emit은 본인에게만 보내는 메시지가 되겠고(확실치 않다),

io.emit은 전체에게 보내는 메소드가 되겠다.

(socket.emit 과 socket.broadcast.emit 두개를 다 쓰면 io.emit과 결과가 같다)

 

소켓 관련 메소드들은 listen 밑에 둘수도 있다고 한다. 그게 더 깔끔해보여서 그렇게 해볼 예정

(라우터로 따로 빼는 법을 찾았음)

 

 

클라이언트측 전문

import React from 'react';
import './Chat.css';
import { useState, useEffect } from 'react';
import io from 'socket.io-client'
let socket;
function Chat() {
const [chatMessage, setChatMessage] = useState("");
const [nickName, setNickName] = useState("익명1");

useEffect(()=>{
    socket = io('http://localhost:3002');
    const ul = document.querySelector("ul");
    socket.on('msg', (msg)=>{
        console.log(msg);
        const li = document.createElement("li");
        li.innerText = msg;
        ul.appendChild(li);
    })
},[])

const handleSubmit = (event)=>{
    event.preventDefault();
    socket.emit('msg', `${nickName} : ${chatMessage}`);
    setChatMessage("");
}
const handleInput = (event)=>{
    setChatMessage(event.target.value);
}

const handleNickname = (event)=>{
    setNickName(event.target.value);
}

    return (
    <>
        닉네임 : <input type="text" onChange={handleNickname} value={nickName}/><br/>
        <hr/>
        <form onSubmit={handleSubmit}>
            <input type="text" onChange={handleInput} value={chatMessage}/>
            <button>전송</button>
        </form>
        <ul></ul>
    </>
    );
}
export default Chat;

 

여기까지 보시면됩니다

https://github.com/wns312/ReadyforSocketIO


파일보내기

 

1) input태그에 파일을 선택하는 type="file" 태그속성이 존재한다. 여기에서 파일을 선택할 수 있고, 이 태그를 form으로 감싸서 onSubmit시 실행할 메소드를 정해주면 될거같긴 하다.

근데 여기서 emit으로 보내는지 axios로 보내는지, 구체적 방법이 어떻게 되는지는 모르겠다. (알아보기)

form 태그에 enctype라는 속성이 있다는데, 이것에 대해서도 알아볼 것 ("multipart/form-data")

multer라는 모듈은 form에 포함된 데이터를 읽어올 때 사용된다.

 

우선 일시 중지하고 인프런 강의를 듣고 되돌아 올 예정임

 

 

 

 

사진보내기

1) 파일로 보내기

 

2) 주소로 보내기 : 얘는 주소만 이미지태그의 속성으로 지정해주면 될거같다.

 

 

2) 방을 만드는 기능을 구현해서, 방마다 다른 채팅방을 만들 수 있도록 하기

 

3) 채팅 내용을 db에 저장할 수 있도록 해보기

 

반응형
LIST
Comments