상세 컨텐츠

본문 제목

socket.io를 이용한 웹 전자칠판

Node.js

by 메타샤워 2023. 7. 19. 14:47

본문

사전 설치 express , socket.io

npm install express
npm install socket.io

1. app.js ( node.js 서버 코드 )

var express = require('express');
var http = require('http');
var fs   = require('fs');
 
var app = express();
 
// express 서버를 6549포트로 구동
var server = app.listen(6549);
 
// express 서버 객체를 socket.io에 연동하고 socket.io 객체 io를 생성
var io = require('socket.io').listen(server);
 
// '/' url로 요청이 들어왔을때 /index.html 파일 보냄 app.js와 index.html 파일은 같은 경로에 존재
app.get('/', function (req,res){
    fs.readFile(__dirname+'/index.html',function(err,data){
        res.writeHead(200,{"Content-Type":"text/html"});
        res.end(data);
    })
});
// 웹 소켓이 연결됐을 때
io.sockets.on('connection', function(socket) {
    // 'linesend' 이벤트로 넘어오는 메세지를 받음
    socket.on('linesend', function(data) {
       // 전송된 메세지 출력
       console.log(data);
       // linesend 이벤트로 넘어오는 메세지를 linesend_toclient 메세지로 보냄
       socket.broadcast.emit('linesend_toclient', data);
     });
});
2. index.html ( app.js와 같은 경로에 위치시킨다.)

 

<!doctype html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html"; chatset="utf-8"/>
    <title> 전자 칠판 </title>
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <style type="text/css">
body{margin: 0px;-webkit-user-select:none; }
        #cv {float : left; border: 1px solid black;}
        #menu { float: left;width: 100px;}
        button, select {width: 100px;height: 50px;float: left;}
        #cv_pen {width: 100px;height: 50px; float: left;}
        fieldset {width: 100px; height: 65px; float: left;}
        #pen_shape{position: absolute;top: 10px;left: 700px;}
    </style>
    <script type="text/javascript">
        // getContext 객체를 전역으로 선언합니다.
        var ctx;
        // socket.io 전역 변수
        var socket;
        // 색상 배열
        var color_map =
        [
            {'value':'red',     'name':'빨간색'},
            {'value':'orange',  'name':'주황색'},
            {'value':'blue',    'name':'파랑색'},
            {'value':'black',   'name':'검은색'},
            {'value':'pink',    'name':'분홍색'},
        ];
        //페이지 로딩 시 시작 부분
       
        $(document).ready(function() {
            // socket.io 전역 변수
            socket = io.connect('http://' + window.location.host);
           
            // jQuery를 이용하여 canvas element 객체 얻기
            ctx = $('#cv').get(0).getContext('2d');
           
            // 색상 선택 select box 설정
            for(var key in color_map)
                $('#pen_color').append('<option>' + color_map[key].name + '</option>');
           
            // 두께  select 설정
            for(var i = 1; i < 16; i++)
                $('#pen_width').append('<option>' + i + '</option>');
 
            // jQuery bin를 이용하여 canvas에 마우스 시작, 이동, 끝 이벤트 핸들러 등록
            $('#cv').on('mousedown', draw.start);
            $('#cv').on('mousemove', draw.move);
            $('#cv').on('mouseup',  draw.end);
 
            // 기본 모양 색상 설정
            shape.setShape();
 
            // clear 버튼에 이벤트 핸들러 등록
            $('#clear').on('click', draw.clear);
 
            // 모양 변경 핸들러등록
            $('select').on('change', shape.change);
 
            // 서버로 부터 받은 데이터 처리 ( 다른 클라이언트에서 그린 draw data )
            socket.on('linesend_toclient', function(data) {
                draw.drawfromServer(data);
            });
        });
 
        var shape = {
            color : 'red',
            width : 3,
            // Select Box 값 변경 시 호출되는 이벤트 핸들러
            change : function(){
               // jQuery에서 선택된 값 읽기
                var color = $('#pen_color option:selected').val();
                for ( var i in color_map )
                    if ( color_map[i].name == color )
                        color = color_map[i].value;
               
               var width = $('#pen_width option:selected').val();
              // 변경 후 shape 객체의 color, width 값 변경하고 펜모양 부분에 라인을 그린다.
              shape.setShape(color,width);
            },
 
            setShape : function(color, width) {
                // 파라미터가 없으면 white, 굵기는 1로 설정합니다.
                if(color != null)
                    this.color = color;
 
                if(width != null)
                    this.width = width;
 
                ctx.strokeStyle = this.color;
                ctx.lineWidth = this.width;
               
                // 펜 모양 부분에 영역을 지움
                ctx.clearRect(703, 0, 860, 90);
               
                // 펜 모양 부분에 라인을 그린다.
                ctx.beginPath();
                ctx.moveTo(710,55);
                ctx.lineTo(820,55);
                ctx.stroke();
            }
        };
        var msg = {
            line : {
                send : function(type,x,y){
                    socket.emit('linesend', {
'type':type, 
'x':x, 
'y':y,
'color':shape.color, 
'width' : shape.width
    });
                }
            }
        };
        // 그리기 부분에 대한 설정
        var draw = {
            drawing : null,
            start : function(e) {  
                ctx.beginPath();
                ctx.moveTo(e.pageX, e.pageY);
                this.drawing = true;
                msg.line.send('start',e.pageX,e.pageY);
            },
            move : function(e) {
                if(this.drawing){
                    ctx.lineTo(e.pageX,e.pageY);
                    ctx.stroke();
                    msg.line.send('move',e.pageX,e.pageY);
                }
            },
            end : function(e){
                this.drawing = false;
                msg.line.send('end');
            },
            clear : function() {
                // 전체 지우기
                ctx.clearRect(0, 0, cv.width, cv.height);
                shape.setShape();
                msg.line.send('clear');
            },
            drawfromServer : function(data) {
                // 그리기 시작 시에 좌표 이동, 색상, 넓이 설정
                if ( data.type == 'start' ){
                    ctx.beginPath();
                    ctx.moveTo(data.x, data.y);
                    ctx.strokeStyle = data.color;
                    ctx.lineWidth = data.width;
                }
                // 그리기
                if (data.type == 'move'){
                    ctx.lineTo(data.x,data.y);
                    ctx.stroke();
                }
                // 그리기 끝남
                if (data.type == 'end'){
                }
                // 전체 지우기
                if(data.type == 'clear'){
                    ctx.clearRect(0, 0, cv.width, cv.height);
                    shape.setShape();
                }
            }
        };
</script>
</head>
<body>
    <canvas id='cv' width="900" height="645"></canvas>
    <div class='menu'>
        <button id = 'clear'>clear</button>
        <fieldset>
            <legend> 색상 변경 </legend>
            <select id ='pen_color'></select>
        </fieldset>
        <fieldset>
            <legend> 펜 두께 </legend>
            <select id ='pen_width'></select>
        </fieldset>
    </div>
    <fieldset id ='pen_shape'>
            <legend> 펜 모양 </legend>
        </fieldset>
</body>
</html>

관련글 더보기