ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • socket.io
    TIL 2020. 9. 16. 23:45

    먼저 이 글은, 학습을 위하여, 아래 사이트의 내용을 따라 적은 내용임을 말씀드립니다.

    poiemaweb.com/nodejs-socketio 

     

     

    HTTP는 무상태(stateless)프로토콜, 어떠한 이정 요청과도 무관한 각각의 요청을 독립적인 트랜잭션으로 취급하는 통신 프로토콜이다.

    이러한 HTTP의 한계에서 벗어나, Node.js에서 손쉽게 실시간 양방향 통신 웹 어플리케이션을 작성할수 있게 해주는 방법은

    socket.io를 사용하는 것이다.

     

    WebSocket은 사용자의 브라우저와 서버사이의 동적인 양방향 연결 채널을 구성하는 프로토콜이다.

    서버로 메세지를 보내고 요청없이 응답을 받는것이 가능하다.

    특정 주기를 가지고 polling 하지 않아도, 변경된 사항을 시기 적절하게 전달할 수 있는 지속적이고 완전한 양방향 연결을 만들어준다.

     

    connection event handler

    io.on('connection', function(socket) {
    
    });

    connection이 수립되면 event handler function 의 인자로 socket이 들어온다

    connection event handler function의 인자로 socket 객체가 전달된다.

    socket 객체는 개별 클라이언트와의 interacting을 위한 기본적인 객체이다.

    io 객체는 연결된 전체 클라이언트와의 interacting을 위한 객체이다

    -> connection event handler function의 인자로 socket객체가 들어온다. socket객체는, 개별 클라이언트와의 interacting을 위한 기본적인 객체이다, io 객체는 연결된 전체 클라이언트와의 interaction(상호작용)을 위한 객체이다.

    -> connection event가 발생하면(클라이언트가 접속하면) 클라이언트가 전송한 메세지를 수신하거나, 클라이언트에게 메세지를 송신한다.

    Server-side

    app.js

     

    클라이언트가 전송한 메세지 수신

    • 현재 접속되어 있는 클라이언트로부터의 메세지를 수신하기 위해서는 on 메소드를 사용한다.
    parameter Description
    event name 클라이언트가 메시지 송신 시, 지정한 이벤트명(string)
    function 이벤트 핸들러. 이벤트 핸들러 함수의 인자로 클라이언트가 송신한 메세지가 전달된다.
    socket.on('eventName', function(data){
      console.log(`Message from client=${data}`)
    }

     

    클라이언트에게 메세시 송신

    Method Description
    io.emit 접속된 모든 클라이언트에게 메세지를 전송한다
    socket.emit 메세지를 전송한 클라이언트에게만 메세지를 전송한다
    socket.broadcast.emit 메세지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메세지를 전송한다
    io.to(id).emit 특정 클라이언트에게만 메세지를 전송한다. id는 socket 객체의 id 속성값이다.
    parameter Description
    event name 이벤트명(string)
    message 송신메세지(string or object)
    //접속된 모든 클라이언트에게 메세지를 전송한다
    io.emit('event_name', message);
    
    //메세지를 전송한 클라이언트에게만 메세지를 전송한다
    socket.emit('event_name', message);
    
    //메세지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메세지를 전송한다
    socket.broadcast.emit('event_name', message);
    
    //특정 클라이언트에게만 메세지를 전송한다
    io.to(id).emit('event_name', data);
    //app.js
    const app = require("express")();
    const server = require("http").createServer(app);
    //http server를 socket.io server로 upgrade
    const io = require("socket.io")(server);
    
    //localhost:3000으로 접속하면 클라이언트로 index.html을 전송한다
    app.get("/", (req, res) => {
      res.sendFile(__dirname + "/index.html");
    });
    
    //connection event handler
    //connection이 수립되면 event handler function 의 인자로 socket이 들어온다
    //connection event handler function의 인자로 socket 객체가 전달된다.
    //socket 객체는 개별 클라이언트와의 interacting을 위한 기본적인 객체이다.
    //io 객체는 연결된 전체 클라이언트와의 interacting을 위한 객체이다
    io.on("connection", (socket) => {
      //접속한 클라이언트의 정보가 수신되면,
      socket.on("login", (data) => {
        console.log(
          `Client logged-in:\n name:${data.name} \n userid:${data.userid}`
        );
        //socket에 클라이언트의 정보를 저장한다.
        socket.name = data.name;
        socket.userid = data.userid;
    
        //접속된 모든 클라이언트에게 메세지를, 전송한다
        io.emit("login", data.name);
      });
    
      //클라이언트로부터의 메세지가 수신되면,
      socket.on("chat", (data) => {
        console.log(`Message from %s %s ${socket.name},${data.message}`);
      });
    
      let message = {
        from: {
          name: socket.name,
          userid: socket.userid,
        },
        message: data.message,
      };
    
      //01.메세지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메세지를 전송한다
      socket.broadcast.emit("chat", message);
    
      //02.메세지를 전송한 클라이언트에게만 메세지를 전송한다.
      //socket.emit('s2c chat', message)
    
      //03.접속된 모든 클라이언트에게 메세지를 전송한다
      //io.emit('s2c chat', message)
    
      //04.특정 클라이언트에게만 메세지를 전송한다
      //io.to(id).emit('s2c chat', data)
    
      //force client disconnect from server
      socket.on("forceDisconnect", () => {
        socket.disconnect();
      });
    
      //접속이 끊겼을 시,
      socket.on("disconnect", () => {
        console.log(`user disconnected: ${socket.name}`);
      });
    });
    
    server.listen(3000, () => {
      console.log("socket IO server listening on port 3000");
    });

    Client-side

    index.html

     

    스크립트 태그에, src attribute값으로 지정해준다. 실제 path를 지정해줄 필요는 없다. socket.io가 서버 가동시, socket.io.js 라이브러리를 자동 생성해주기 때문이다.

    socket.io 서버에 접속하기 위해, io() 메소드를 호출한다. 이때, 생성된 socket으로, 서버로의 메세지를 송수신 할 수 있게 된다.

    <script src="/socket.io/socket.io.js"></script>
    
    //socket.io 서버에 접속
    var socket = io();

     

    서버로의 메세지 송신

    • 현재 접속되어 있는 서버로 메세지를 송신하기 위해서는 emit 메소드를 사용한다.
    parameter Description
    event name 이벤트명(string)
    message 송신 메세지(string or object)
    socket.emit("event_name", message)

    서버로부터의 메세지 수신

    • 현재 접속되어 있는 서버로부터의 메세지를 수신하기 위해서는 on 메소드를 사용한다,
    parameter Description
    event name 서버가 메세지 송신 시 지정한 이벤트명(string)
    function 이벤트핸들러, 핸들러 함수의 인자에 서버가 송신한 메세지가 전달된다
    socket.on("event_name", function(data){
      console.log(`Message from server: ${data}`)
    });

     

    NameSpace

    socket.io는 서로 다른 엔드포린트 또는 경로를 할당하는 의미로 socket에 namespace를 지정할 수 있다.

    namespace를 특별히 지정하지 않은 경우 default namesapce인, / 를 사용하게 된다.

    사용자 지정 namespace를 사용할 경우의 예제는 아래와 같다.

    //Server-side
    
    var nsp = io.of('/my-namespace')
    
    nsp.on('connection', function(socket){
      console.log('someone connected')
    });
    nsp.emit('hi', 'everyone')
    
    //Client-side ,, 지정namespace로 접속한다
    
    var socket = io('/my-namespace')
    

     

    Room

    각 네임스페이스 내에서 임의의 채널을 지정할 수 있다. 이를 room 이라고 하며, 이를 통해 room에 join 되어 있는 클라이언트 만의 데이터 송수신이 가능하게 된다. 즉 각 클라이언트는 socket을 가지게 되며, 이 socket은 namesapce를 가지고 각 namespaces는 room을 가질 수 있다.

    'TIL' 카테고리의 다른 글

    완주하지 못한 선수  (0) 2020.09.18
    sequelize ORM 날짜관련 해결문제.  (0) 2020.09.17
    나누어 떨어지는 숫자 배열(프로그래머스)  (0) 2020.09.15
    두개 뽑아서 더하기(프로그래머스)  (0) 2020.09.15
    webSocket - 01  (0) 2020.09.10

    댓글

Designed by Tistory.