ecsimsw

Socket.io 본문

Socket.io

JinHwan Kim 2019. 1. 22. 13:17

Socket

- node.js에서 socket을 이용하여 통신하는 방법을 공부하고, 학습 예제로 웹 채팅 서버/어플리케이션을 제작하고, 나아가 이 서버로 c#/ android 클라이언트가 통신하는 방법을 공부할 생각이다.
  • socket.io
    - node.js에선 socket.io 모듈을 통해 소켓 통신을 할 수 있다.
    npm install socket.io --save
    server에서 Express를 사용하여 Http 서버를 생성하고 생성된 Http 서버를 socket.io server에 연결한다.
    var app = require('express')(); var server = require('http').createServer(app); var io = require('socket.io')(server); server.listen(3000, function(){ console.log('listening on port:3000'); })
    ## 앱이 서버를 시작하여 3000번 포트를 listen하는게 아니라 이번에는 http 서버이므로 server.listen을 해야하는 것에 유의한다.
      위 서버를 청취하는 app.listen과 server.listen 차이를 다시 공부한다. stackoverflow: app.listen vs server.listen
    - client에선 script에서 tag의 src 어트리뷰트값으로 “/socket.io/socket.io.js”만 다음처럼 지정해주면 된다. socket.io가 서버 기동 시에 socket.io.js 라이브러리를 자동으로 생성한다.
    <script src="/socket.io/socket.io.js"></script>
    이렇게 서버와 클라이언트에서 socket.io 모듈을 사용할 준비를 마친다.
  • connection
    - 클라이언트에서 다음으로 서버에 접속한다.
    const socket = io();
    - 클라이언트가 연결되면 서버로 connection 이벤트를 발생시킨다. 다음처럼 connection event handler을 정의하는 것으로 이를 처리할 수 있다.
    io.on('connection', function(socket) { console.log('user connected'); }) })
  • event handler
    - 접속되어 있는 소켓의 이벤트를 발생시키고 리슨하여 메세지를 송/수신한다.
      이벤트는 다음으로 handle하고, emit한다.
    "event handler" socket.on('event_name', function(data) { console.log(data); }); "event emitter" socket.emitMethod('event_name',data);
    - 다음의 emit method를 통해 연결된 socket에 이벤트를 발생시킬 수 있다.
    io.emit 접속된 모든 클라이언트에게 메시지를 전송한다.
    socket.emit 메시지를 전송한 클라이언트에게만 메시지를 전송한다.
    socket.broadcast.emit 메시지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메시지를 전송한다.
    io.to(id).emit 특정 클라이언트에게만 메시지를 전송한다. id는 socket 객체의 id 속성값이다.
    - 이것을 참고하여 클라이언트가 connect된 상태에서 submit_by_client라는 이벤트가 발생하면 이 데이터를 emit_by_server라는 이벤트 명으로 연결된 모든 클라이언트에게 전송하였다.
    "server.js" io.on('connection', function(socket) { console.log('user connected'); socket.on('submit_by_client', function(msg){ io.emit('emit_by_server',msg); }) })
    - 클라이언트는 form에서 submit 이벤트가 발생하면 name, message id가 있는 input을 각각 가져와 msg 객체의 name, message 변수에 저장하고 이를 submit_by_client라는 이름으로 이벤트를 발생시킨다.
      서버와 마찬가지로 emit_by_server 이벤트 핸들러를 정의하여 서버에서 오는 데이터(msg 객체)를 받아 이를 처리하여 대화 로그 박스에 출력한다.
    "client.html" $('#textBox').on('submit', function(event){ var msg={ name:$('#name').val(), message:$('#message').val() }; socket.emit('submit_by_client', msg); $('#message').val(''); $('#message').focus(); event.preventDefault(); }); socket.on('emit_by_server', function(msg){ $('#logBox').append(msg.name+' : '+msg.message+'\n'); $('#logBox').scrollTop($('#logBox')[0].scrollHeight); });
  • Code
    server.js "server.js" var app = require('express')(); var server = require('http').createServer(app); var io = require('socket.io')(server); app.get('/',function(req,res){ res.sendFile(__dirname +'/socketClient/client.html'); }) io.on('connection', function(socket) { console.log('user connected'); socket.on('submit_by_client', function(msg){ io.emit('emit_by_server',msg); }) }) server.listen(3000, function(){ console.log('listening on port:3000'); }) client.html "client.html" <head> <script type="text/javascript">if (!window.T) { window.T = {} } window.T.config = {"TOP_SSL_URL":"https://www.tistory.com","PREVIEW":false,"ROLE":"guest","PREV_PAGE":"","NEXT_PAGE":"","BLOG":{"id":3020396,"name":"ecsimsw","title":"ecsimsw","isDormancy":false,"nickName":"JinHwan Kim","status":"open","profileStatus":"normal"},"NEED_COMMENT_LOGIN":false,"COMMENT_LOGIN_CONFIRM_MESSAGE":"","LOGIN_URL":"https://www.tistory.com/auth/login/?redirectUrl=https://ecsimsw.tistory.com/entry/Socketio","DEFAULT_URL":"https://www.blog.ecsimsw.com","USER":{"name":null,"homepage":null,"id":0,"profileImage":null},"SUBSCRIPTION":{"status":"none","isConnected":false,"isPending":false,"isWait":false,"isProcessing":false,"isNone":true},"IS_LOGIN":false,"HAS_BLOG":false,"IS_SUPPORT":false,"IS_SCRAPABLE":false,"TOP_URL":"http://www.tistory.com","JOIN_URL":"https://www.tistory.com/member/join","PHASE":"prod","ROLE_GROUP":"visitor"}; window.T.entryInfo = {"entryId":51,"isAuthor":false,"categoryId":813251,"categoryLabel":"Server application/Node.js"}; window.appInfo = {"domain":"tistory.com","topUrl":"https://www.tistory.com","loginUrl":"https://www.tistory.com/auth/login","logoutUrl":"https://www.tistory.com/auth/logout"}; window.initData = {}; window.TistoryBlog = { basePath: "", url: "https://www.blog.ecsimsw.com", tistoryUrl: "https://ecsimsw.tistory.com", manageUrl: "https://ecsimsw.tistory.com/manage", token: "e8z0EfO1iqNB56iY9CxlDY9vT3g/WkAvLGKaRd06dXjiWFMrSko3NyTHd1BZfkAk" }; var servicePath = ""; var blogURL = "";</script> <meta charset="utf-8"> <title>Chat</title> <style> .logBox{ width: 350px; height: 400px; } .name{ width: 44px; } .message{ width: 300px; } .submit{ display: none; } #textBox{padding-bottom: 10px;} </style> <style type="text/css">.another_category { border: 1px solid #E5E5E5; padding: 10px 10px 5px; margin: 10px 0; clear: both; } .another_category h4 { font-size: 12px !important; margin: 0 !important; border-bottom: 1px solid #E5E5E5 !important; padding: 2px 0 6px !important; } .another_category h4 a { font-weight: bold !important; } .another_category table { table-layout: fixed; border-collapse: collapse; width: 100% !important; margin-top: 10px !important; } * html .another_category table { width: auto !important; } *:first-child + html .another_category table { width: auto !important; } .another_category th, .another_category td { padding: 0 0 4px !important; } .another_category th { text-align: left; font-size: 12px !important; font-weight: normal; word-break: break-all; overflow: hidden; line-height: 1.5; } .another_category td { text-align: right; width: 80px; font-size: 11px; } .another_category th a { font-weight: normal; text-decoration: none; border: none !important; } .another_category th a.current { font-weight: bold; text-decoration: none !important; border-bottom: 1px solid !important; } .another_category th span { font-weight: normal; text-decoration: none; font: 10px Tahoma, Sans-serif; border: none !important; } .another_category_color_gray, .another_category_color_gray h4 { border-color: #E5E5E5 !important; } .another_category_color_gray * { color: #909090 !important; } .another_category_color_gray th a.current { border-color: #909090 !important; } .another_category_color_gray h4, .another_category_color_gray h4 a { color: #737373 !important; } .another_category_color_red, .another_category_color_red h4 { border-color: #F6D4D3 !important; } .another_category_color_red * { color: #E86869 !important; } .another_category_color_red th a.current { border-color: #E86869 !important; } .another_category_color_red h4, .another_category_color_red h4 a { color: #ED0908 !important; } .another_category_color_green, .another_category_color_green h4 { border-color: #CCE7C8 !important; } .another_category_color_green * { color: #64C05B !important; } .another_category_color_green th a.current { border-color: #64C05B !important; } .another_category_color_green h4, .another_category_color_green h4 a { color: #3EA731 !important; } .another_category_color_blue, .another_category_color_blue h4 { border-color: #C8DAF2 !important; } .another_category_color_blue * { color: #477FD6 !important; } .another_category_color_blue th a.current { border-color: #477FD6 !important; } .another_category_color_blue h4, .another_category_color_blue h4 a { color: #1960CA !important; } .another_category_color_violet, .another_category_color_violet h4 { border-color: #E1CEEC !important; } .another_category_color_violet * { color: #9D64C5 !important; } .another_category_color_violet th a.current { border-color: #9D64C5 !important; } .another_category_color_violet h4, .another_category_color_violet h4 a { color: #7E2CB5 !important; } </style> <link rel="stylesheet" type="text/css" href="https://tistory1.daumcdn.net/tistory_admin/userblog/userblog-9f215d513ac1c1fc530f1b625c346be762e46741/static/style/revenue.css"/> <link rel="canonical" href="https://www.blog.ecsimsw.com/entry/Socketio"/> <!-- BEGIN STRUCTURED_DATA --> <script type="application/ld+json"> {"@context":"http://schema.org","@type":"BlogPosting","mainEntityOfPage":{"@id":"https://www.blog.ecsimsw.com/entry/Socketio","name":null},"url":"https://www.blog.ecsimsw.com/entry/Socketio","headline":"Socket.io","description":"Socket - node.js에서 socket을 이용하여 통신하는 방법을 공부하고, 학습 예제로 웹 채팅 서버/어플리케이션을 제작하고, 나아가 이 서버로 c#/ android 클라이언트가 통신하는 방법을 공부할 생각이다. socket.io - node.js에선 socket.io 모듈을 통해 소켓 통신을 할 수 있다. npm install socket.io --save server에서 Express를 사용하여 Http 서버를 생성하고 생성된 Http 서버를 socket.io server에 연결한다. var app = require('express')(); var server = require('http').createServer(app); var io = require('socket.io')(server)..","author":{"@type":"Person","name":"JinHwan Kim","logo":null},"image":{"@type":"ImageObject","url":"https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99D52B4F5C46DF4923","width":"800px","height":"800px"},"datePublished":"2019-01-22T13:17:29+09:00","dateModified":"2019-01-24T23:20:16+09:00","publisher":{"@type":"Organization","name":"TISTORY","logo":{"@type":"ImageObject","url":"https://t1.daumcdn.net/tistory_admin/static/images/openGraph/opengraph.png","width":"800px","height":"800px"}}} </script> <!-- END STRUCTURED_DATA --> <link rel="stylesheet" type="text/css" href="https://tistory1.daumcdn.net/tistory_admin/userblog/userblog-9f215d513ac1c1fc530f1b625c346be762e46741/static/style/dialog.css"/> <link rel="stylesheet" type="text/css" href="//t1.daumcdn.net/tistory_admin/www/style/top/font.css"/> <link rel="stylesheet" type="text/css" href="https://tistory1.daumcdn.net/tistory_admin/userblog/userblog-9f215d513ac1c1fc530f1b625c346be762e46741/static/style/postBtn.css"/> <link rel="stylesheet" type="text/css" href="https://tistory1.daumcdn.net/tistory_admin/userblog/userblog-9f215d513ac1c1fc530f1b625c346be762e46741/static/style/tistory.css"/> <script type="text/javascript" src="https://tistory1.daumcdn.net/tistory_admin/userblog/userblog-9f215d513ac1c1fc530f1b625c346be762e46741/static/script/common.js"></script> </head> <script src="/socket.io/socket.io.js"></script> <script src="//code.jquery.com/jquery-1.11.1.js"></script> <script> var socket = io(); $('#textBox').on('submit', function(event){ var msg={ name:$('#name').val(), message:$('#message').val() }; socket.emit('submit_by_client', msg); $('#message').val(''); $('#message').focus(); event.preventDefault(); //.val() : to get or set value of the form // preventDefault : for cancelling refresh attempt that is by submit event }); socket.on('emit_by_server', function(msg){ $('#logBox').append(msg.name+' : '+msg.message+'\n'); $('#logBox').scrollTop($('#logBox')[0].scrollHeight); }); </script> <h4>Client</h4> <div> <form id="textBox"> <input id="name" class="name" type="text"> <input id="message" class="message" type="text"> <input type="submit" class="submit" value="submit"> </form> </div> <div> <textarea id="logBox" class="logBox" readonly></textarea> </div>
  •  

'Server application > Node.js' 카테고리의 다른 글

Net  (0) 2019.01.23
GET / POST  (0) 2019.01.20
FileStream / Querystring  (0) 2019.01.19
Serving static files / Grave accent  (0) 2019.01.16
Template engine / pug  (0) 2019.01.15
Comments