프론트에서 Obj형을 string형으로 변환하여 백으로 전송
백에서는 다시 Obj형으로 변환하여 저장
: 실시간 작동, 양방향 통신, 이벤트 기반 통신을 제공하는 프레임워크
웹소켓은 SocketIO를 실행하는 방법 중 하나임
npm i socket.io
server.js
import {Server} from "socket.io" const wsServer = new Server(server);
home.pug
script(src="/socket.io/socket.io.js")
app.js
const socket = io();
io() : socket.io를 실행하고 있는 서버와 연결해주는함수
프론트에서 emit했다면 해당 이벤트를 감지하는 socket.on이 백에 있어야 하고
백에서 emit했다면 해당 이 벤트를 감지하는 socket.on이 프론트에 있어야함
app.js
socket.emit("발생할 이벤트 명", argument들) <-이벤트명 작명가능!
웹소켓에선 socket.on("close/open/message 등")
- argument들 :
object형도 가능!! 여러 개 가능
socket.emit("enter_room", {payload: input.value }, 5,'abcd',true )
끝날때 실행시키고 싶다면 꼭 마지막에 콜백함수
여기서 socket : "connection"이벤트가 발생한 this
app.js
server.js
프론트에서 form을 submit하면 지정한 이벤트명의 이벤트 발생시킴
백에선, 서버와 브라우저가 연결되고, 그 해당 이벤트명이 발생하면 프론트에서 전송한 argument에 접근하여 사용할 수 있음.
🌟 argument 마지막의 함수를 백에서 호출하지만 실행은 프론트에서하는 것!! 보안상
EventListener 인 셈. 이벤트가 발생하는지 확인할 수 있음
app.js
- onAny에서
console.log(event) >>> enter_room
-> 아랫줄 socket.on("enter_room" ... 에서 'enter_room"이란 함수를 발생시키니까- 웹소켓에선 사용못하는 기능!! 왜 ? 웹소켓에서는 socket.on("message"만 있었으니까.
console.log(socket.rooms);
를 하면Set(2) { 'oIrKj6aysbjtaLcvAAAE', 'newRoom' }
이런 식으로 뒤에 룸명 추가됨Adds the socket to the given room or to the list of rooms.
room을 추가할수있다. ("룸1")로 하나 뿐 아니라 (["룸2","룸3"])등 여러개를 리스트로 추가할 수 도 있다.
해당하는 (방 혹은 전체)에 메세지나 이벤트 등을 보낼 수 있음
단, 나는 제외 !!
모두에게 보낼때는 socket.emit()였다.
ex ) 백에서 socket.to(roomName).emit("welcome", socket.nickname);
이란 코드로 welcome이란 이벤트를 전송했다면, 프론트에서 이 이벤트에 대해 반응하도록 socket.on("welcome",(user) => {addMessage(
${user} arrived!)});
설정해야한다.
메세지 제출 form 처럼 닉네임 form을 만들고 이벤트 연결
app.js
- handleNicknameSubmit()에서 "nicknameSave"란 이벤트와 입력값 전송.
server.js
- 서버가 연결되면 소켓에 아이템으로 nickname을 저장해둔다.
- nicknameSave가 발생하면 인자로 넘어온 입력값(여기선 닉네임)을 socket의 아이템nickname의 값으로 저장해둔다.
- 다른 이벤트에서 socket.nickname으로 접근하여 닉네임을 사용할 수 있다.
다른 서버들 사이에 실시간 어플리케이션 동기화
지금까진, 서버 다시 시작할때마다 룸,메세지 다 사라지고 다시시작인데,
이제 데이터베이스로 가지고 있도록 하려면 필요!!
"enter_room" 발생 이후 console.log(wsServer.sockets.adapter)
해보면
const newMap = new Map()
newMap.set("keyname", valuename)
>> Map(1) {"keyname" => valuename}
백엔드에 연결된 모든 소켓들의 Map구조인 sids를 갖고있음
forEach를 사용하여 Public룸의 id만 가지고 있는 변수 만들기
function publicRooms(){
const {
sockets: {
adapter : {sids, rooms},
},
} = wsServer;
//위랑 같은거
// const sids = wsServer.sockets.adapter.sids;
// const rooms = wsServer.sockets.adapter.rooms;
//혹은 const { rooms, sids } = wsServer.sockets.adapter;
const publicRooms = [];
rooms.forEach((_,key) =>{
if (sids.get(key) === undefined){ //sid에 없다면 public
publicRooms.push(key);
}
})
return publicRooms;
}
모든 소켓에게 메세지 보낼땐 그냥sockets.emit이 아니라 서버.sockets.emit
admin-UI
npm i @socket.io/admin-ui
vsCode에서 오류 발생시 윈도우 cmd에서 실행
server.js
import {instrument} from "@socket.io/admin-ui";
const wsServer = new Server(server,{ cors: { origin: ["https://admin.socket.io"], credentials: true } }); instrument(wsServer, { auth: false });
새 시크릿창으로 https://admin.socket.io/ 접속
💥Error: xhr poll error
🌻서버 켰는지 확인! npm run dev