프로토콜 HTTP와 WEBSOCKET의 차이점
HTTP : stateless
backend가 유저를 기억하지 못한다는 뜻 ,reply만 가능함
http://
WSS: 양방향
악수처럼 진행됨 처음에 req 보내고 accept하면 연결은 성립되는 것
연결되어있으면 브라우저와 서버는 어느 때나 메세지를 보낼 수 있음
브라우저에는 내장된 websocket api가있음
wws://
웹소켓의 기본이되는 ws
npm i ws로 설치
특징:부가적인기능 없음 완전 기본코드
ws서버와 express서버를 합칠 것임
항상 이런식으로 코드를 두개 작성하지 않아도되지만
두개 모두 같은 포트에서 작동하게하고싶어서
http서버 위에 ws서버를 만들기위함
http,ws reqeust를 같은 포트에서 처리 할 수 있음
--Big Issue---
"ws": "^8.2.3" 버전부터는
Websocket.Server 가 아니라 WebSocketServer 입니다.
아래 문서를 참고하세요 https://www.npmjs.com/package/ws
내 버전은 8.1.3
프론트엔드에서는 웹소켓 설치할 필요없음
백엔드와 연결만하면 됨
wss.on작동은 이벤트핸들러와 매우흡사함
on method는 backend에 연결된 사람의 정보를 제공해줌 socket(서버와 브라우저의연결)
console.log(socket);
});
연결이 없기에 지금은 아무런 활동이 일어나지 않음
프론트엔드에 백엔드와 연결해달라고해야함
연결하는 법
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
server.js의 socket은 연결된 브라우저를 뜻함
app,js 의 socket은 서버로의 연결
나는 헷갈려서 각각 backSocket , frontSocket 으로 지정함
socket에 있는 메서드를 사용해보자 서버,ws의 매서드 아님
메세지를 보내긴했지만
프트엔드에서 받지않아서 안뜸
server.js
wss.on("connection", (socket)=> {
console.log("Connected to Browser ✅"); //브라우저열면
socket.send("hello!!");
socket.on("close", () =>console.log("Disconnected from Browser ❌"));//브라우저 닫으면
});
app.js
const socket = new WebSocket(`ws://${window.location.host}`);
socket.addEventListener("open", ()=>{
console.log("Connected to Server ✅") //서버연결되면
});
socket.addEventListener("message", (message)=>{ //send로 보낸게 message이벤트임
console.log("New message:", message.data,"from the server");
});
socket.addEventListener("close",()=>{
console.log("Disonnected to Server ❌");//서버 종료하면
})
반대로 브라우저에서 서버로 메세지보내기
app.js
setTimeout(()=>{
socket.send("hello from browser"); 10초후에 보내면
},10000)
server.js
wss.on("connection", (socket)=> { // 버튼을 리스닝하고 이벤트를 받아서 처리한 것과 같다. wws는 전체 서버
console.log("Connected to Browser ✅"); /
socket.on("close", () =>console.log("Disconnected from Browser ❌")); //종료됐을 때 //각 socket(브라우저)에대한 처리
socket.on("message", (message)=>{ //메시지 이벤트 받아서 콘솔창에 나타내기
console.log(message.toString('utf8);
})
socket.send("hello!!"); //보내기
});
form 만들어서 back으로 보내고 다시 back에서 front로 보내기
app.js
function handleSubmit(event){
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(input.value);
input.value = "";
}
messageForm.addEventListener("submit", handleSubmit);
server.js
wss.on("connection", (socket)=> {
console.log("Connected to Browser ✅");
socket.on("close", () =>console.log("Disconnected from Browser ❌"));
socket.on("message", (message) => {
socket.send(message.toString());
});
});
--- 메세지가 바로 front로 전달됨 하지만 혼자 티카타카는 의미없고
각가 브라우저에 티키타카가 되도록 삼각형 구도를 만들고싶음 그럴려면
누가 연결이 되었는지 알아야함
const sockets = [];
wss.on("connection", (socket)=> { //연결이 된 각 소켓을
sockets.push(socket); //sockets 배열에 넣고
console.log("Connected to Browser ✅");
socket.on("close", () =>console.log("Disconnected from Browser ❌"));
socket.on("message", (message) => { //어느곳에서 메세지를 받으면
sockets.forEach((aSocket) => aSocket.send(message.toString())); //배열 내의 각각 의 소켓에 전달
});
});
html에 나타내기 app.js
socket.addEventListener("message", (message)=>{
const li = document.createElement("li");
li.innerText = message.data;
messageList.append(li);
});
닉네임 지정하기
html에 위와 같이 form을 만들어서 보내면
nickname도 li에 추가가된다.
이 두개의 폼에 이름을 붙혀야할 것같다.
json형식으로 socket.send보내기
function makeMessage(type,payload){
const msg= {type, payload} 타입과 내용을 객체로받아서
return JSON.stringify(msg); 문자화해서 백엔드로 보내기
}
function handleSubmit(event){
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message", input.value));
input.value = "";
}
function handleNickSubmit(event){
event.preventDefault();
const input = nickForm.querySelector("input");
socket.send(makeMessage("nickname", input.value));
}
백엔드로 javascript object객체를 보내는것은 안좋음 연결하고 싶은 프론트와 백엔드가 자바스크립트 서버가아닐 수잇음 JAVA, GO등 그래서 STRING을 보내고 결정하는 것
wss.on("connection", (socket)=> {
sockets.push(socket);
socket["nickname"] ="익명"; //socket에 정보를 추가할 수 있음 //소켓 배열에 여러가지 정보가 있을 텐데 거기에다가
console.log("Connected to Browser ✅");
socket.on("close", () =>console.log("Disconnected from Browser ❌"));
socket.on("message", (msg) => {
const message = JSON.parse(msg); //객체로 변환해서
switch(message.type){ //메세지타입이
case "new_message":
sockets.forEach((aSocket) => aSocket.send(`${socket.nickname}: ${message.payload}`));
break; //switch문에서 꼭 break를 해줘야 혼선이 안생기고 더이상 찾지 않고 끊음
case "nickname":
socket["nickname"] = message.payload;
break;
}
});
});
개선
1.
app.js
socket.addEventListener("message", (message)=>{
const li = document.createElement("li"); li.innerText = message.data; messageList.append(li);
});
function handleSubmit(event){
event.preventDefault();
const input = messageForm.querySelector("input");
socket.send(makeMessage("new_message", input.value));
const li = document.createElement("li");
li.innerText = `You : ${input.value}`;
messageList.append(li);
input.value = "";
}
내가 글을 적고 제출 버튼을 눌렀을 때 화면상에 나타남
이제 글자를 입력하고 제출을하게되면
front에서 보낸 글자와
서버에서 보낸 글자 두개가 나타남
2.나를 제외한 사람들에게 메세지를 보내고싶음
'코딩 > Today I Learn' 카테고리의 다른 글
3.3목 (0) | 2022.03.03 |
---|---|
Zoom 클론코딩 #3 SoketIO (0) | 2022.03.03 |
Zoom 클론코딩 #1 환경설정 (0) | 2022.02.26 |
2.19토 (0) | 2022.02.26 |
02.15화 (0) | 2022.02.17 |