노드 웹소켓통신시 특정 소켓에 메시지 전송하는 방법 문의

노드 웹소켓통신시 특정 소켓에 메시지 전송하는 방법 문의

QA

노드 웹소켓통신시 특정 소켓에 메시지 전송하는 방법 문의

답변 3

본문

노드를 이용해서 서버를 만들고 통신하는 채팅앱을 만드는중인데 모를것이 있어서 지척거리다고 고수님들 의견을 받고저 글 올립니다


wss.on("connection", ws => {
    console.log("new client connected");
    client_id = Date.now();
    clients.set(client_id, ws);
    // sending message
    ws.on('message', function(message) {
        //wss.broadcast(JSON.stringify(message));
       
        console.log('Received: ' + message);
        BetFunc(JSON.parse(message), ws);
        //console.log()
      });
    ws.on("close", () => {
        console.log("the client has connected");
    });
    ws.onerror = function () {
        console.log("Some Error occurred")
    }
    // ws.send('You successfully connected to the websocket.');
});

일단 이렇게 만들었는데 특정 유저에게만 어떻게 전달할지 모르겠습니다
웹소켓고수분들 방조 부탁드립니다, 감사합니다.

이 질문에 댓글 쓰기 :

답변 3

    client_id = Date.now();
    clients.set(client_id, ws);

에서 clients는 map 객체 인가요?????
그렇게 이해하고 설명 드리겠습니다.

connection 이 일어나자 마자 클라이언트의 고유 값을 가지게 했잔아요.
첫 커넥션에서 클라이언트의 ip나 특정할 수 있는 값을 파싱해서 배열에 처음에 넣는 것도 
가능하겠지만 적당한 선에서
설명 드리자면 첫 커넥션이 일어나고 클라이언트에서 강제로 메세지를 보냅니다. 
로그인이라고 임의로 정하겠습니다.
type을 login이라고 하고 그누보드 아이디 같은걸 바로 보냅니다.
서버에서 type이 memberlist로 들어오면 접속자 정보를 배열에다 담습니다.
클라이언트는 접속자 정보(id)를 보고 현재 접속자 중 선택해서 메세지를 보내면 됩니다.


//클라이언트 소스
var memberlist;
const webSocket = new WebSocket("ws://localhost:8005");
webSocket.onopen = function() {
    console.log('서버와 웹소켓 연결 성공!');
    var msg = {
        type : "login",
        id : 'aaaaa' // 내 그누보드 맵버 아이디 같은거
    };
    webSocket.send(JSON.stringify(msg));
};

webSocket.onmessage = function(event) {
    var jsonMsg = JSON.parse(event.data);
    if(jsonMsg.type == "memberlist"){ 
        memberlist = jsonMsg.list;
    }else if(jsonMsg.type == "msg"){
        alert(jsonMsg.myId+"에게서 온 메세지 : "+ jsonMsg.myId);
    }
};

function sendToMember(id,msg){
    if(memberlist.indexOf(id) >= 0){ // 접속된 맴버가 맞는지 확인
        var msg = {
            type : "msg",
            myId : "aaaaa", // 내 그누보드 맵버 아이디 같은거
            youId : id, // 그누보드 상대 맵버 아이디 같은거
            msg : msg
        };
        webSocket.send(JSON.stringify(msg));
    }
}

sendToMember("bbbb","안녕하세요!!");

서버는 대충 클라이언트가 메세지 type을 login으로 보내오면 접속자 들을 clients에 담고 전체에 브로드 케스팅 해서 현재 접속자들을 전체에 알려줍니다. 클라이언트가 type을 msg로 보내면 youId를 보고 그 ws 객체로만 메세지를 보냅니다. 사실 접속자 삭제 로직도 있어야지만 대충 이런식으로 json 가지고 서로 서버와 클라이언트간 통신을 하면됩니다.

// 서버소스
var clients = new Map();
wss.on("connection", ws => {
    console.log("new client connected");
    // sending message
    ws.on('message', function(message) {
        var jsonMsg = JSON.parse(message);
        if(jsonMsg.type == "login"){
            clients.set(jsonMsg.id, ws);    
            var msg = {
                type : "memberlist",
                list : Array.from( clients.keys() ) // 그누보드 상대 맵버 아이디 같은거
            };
            wss.broadcast(JSON.stringify(msg));    
            
        }else if(jsonMsg.type == "msg"){
            var youId = jsonMsg.youId;
            clients.get(youId).send(JSON.stringify(jsonMsg));
        }
    });
    ws.on("close", () => {
        console.log("the client has connected");
    });
    ws.onerror = function() {
        console.log("Some Error occurred")
    }
    // ws.send('You successfully connected to the websocket.');
});
여튼 위와 같이 json을 통해 서로 약속된 프로토콜을 설정하여 다양한 형태의 메세지를 보내거나 때에 따라선 브로드케스트나 특정 유저에게 메세지를 보낼 수 있을 겁니다. 코드는 테스트 하지 않았습니다. node 셋팅이 안되어 있어서 대충 짰습니다.

 

마지막으로 채팅을 구현 하시고 싶으시면 웹소켓(ws)보다는

socket.io 로 개발하세요. 훨신 명시적이고 확장이 가능합니다.

채팅 구현에 더 적합합니다.

정말 상세한 답변에 감사드립니다.
중급규모의 서버를 node로 만들어야 하는데 클래스로 파일 구현을 진행하려는데 혹시 어디 샘플될만한 링크같은게 없을가요.
깃허브 오픈소스같은 링크라도 좀 올려주시면 고맙겠습니다.

Socket.io-redis cluster

검색해보세요. redis로 클러스터 가능하고 몇천, 몇만 가능합니다.

https://library.gabia.com/contents/8018/
참고

nats.io도 검색해보세요. redis 보다 7배 성능향상이 있다고 하네요.

https://channel.io/ko/blog/real-time-chat-server-2-redis-pub-sub

결국 서버 한대로는 중급규모가 어느정도 인지 모르겠으나 클러스터 구축은 두 기술로 쉽게 가능합니다.

예전에 클러스터 구축 안하고 테스트한 경험상 2천은 동접해서 서비스 가능했습니다. 불안불안 했지만요.

답변을 작성하시기 전에 로그인 해주세요.
QA 내용 검색
질문등록
전체 95
© SIRSOFT
현재 페이지 제일 처음으로