반응형

NodeJS 로 채팅 서비스 만들기

시스템 소프트 웨어 강의를 배우면서 리눅스를 이용한 c 코드 C - S 를 만들어보니 재미가 있어 NodeJS 로 구현해 보기로 했다.

위의 링크를 통해 배우고 구현해 보기로 했다.

필요 모듈

const fs = require('fs');
// express module
const express = require('express');
// socket module
const socket = require('socket.io');
// html module
const http = require('http');

NodeJS 기본 모듈을 제외하면 express, socket.io 모듈이 추가로 필요하다.

Socket.io module

Socket.io 에 대한 함수를 알아보자

  • socket.on(’event’, Callback func) : 해당 이벤트를 받고 콜백함수를 실행
  • socket.emit(’event’, Data) : 이벤트 명을 지정하고 데이터 보냄
    • event 종류
      • connection : client 와 연결시 발생
      • disconnection : client 와 연결해제되었을 때 발생

Socket 은 객체 io 를 생성한다.

const io = socket(server)

생성된 io 를 이용해 데이터를 주고 받는 함수를 만들 수 있다.

main.js 에 만든 이벤트 함수들은 총

  • newUser
  • message
  • disconnect

이며 이를 코드로 표현하면

io.sockets.on('connection', function(socket){

    socket.on('newUser', function(name){
        socket.name = name
        // newUser 이벤트로 가져온 name 을 update 이벤트로 데이터 전송
        io.sockets.emit('update', {type : 'connect', name:'SERVER', message: name + 'was connected'})
    })

    socket.on('message', function(data){
        data.name = socket.name
       // message 이벤트로 가져온 data 를 다른 client 에게 update 할 데이터 전송
        socket.broadcast.emit('update', data)
    })

    socket.on('disconnect', function(){
        socket.broadcast.emit('update', {type : 'disconnect', name:"SERVER", message : socket.name + 'Disconnected'})
    })
})

라고 표현할 수 있다.

홈페이지에 접속하면 사용자의 이름을 받는다.

socket.on('connect', function(){
    var name = prompt('Welcome', '')

    if(!name){
        name = 'Annonymous'
    }
    socket.emit('newUser', name)
})

prompt 를 이용해 이름을 입력받아 emit 하여 newUser를 실행한다.

이어 input 박스에 적은 메시지를 채팅창에 표현해보려고 한다.

반응형

'Web > NodeJS' 카테고리의 다른 글

[NodeJS] 1.DB연동  (0) 2022.01.29
반응형

HTTP module

var http  = require('http');
//http module 불러오기

var url = require('url');
// url module 불러오기

http.createServer(function(request,response){
    // http module 을 이용하여 서버 생성

    var pathname = url.parse(request.url).pathname;
    //url 뒤에 있는 디렉토리 / 파일 이름 파싱

    if(pathname=="/"{// pathname 이 비어있다면 index를 디폴트로
        pathname="/index.html";    
    }
}

 

콜백함수를 사용해 response 이벤트가 감지되면 데이터를 데이터에 받아온다.

 

var callback = function(response){
    var body='';
    response.on('data',function(data){
        body += data;    
    };
}

Mysql module

NodeJS 에서 DB 연동을 해보려고 한다.

 

const express = require('express')
const app = express();

 

express 를 불러와 app 에 할당한다.

 

var mysql = require('mysql');
var pool = mysql.createPool({
    connectionLimit : 10,
    host :"localhost",
    user : "root",
    password : "0000",
    database : "moviestar"
})

 

require(’mysql’) 은 mysql 모듈을 사용하겠다라는 뜻.

mysql 을 실행하기 위한 pool 을 생성한다.

 

app.get('/db',function(req,res){
    pool.getConnection(function(err, connection){

        if(err) throw err;

        connection.query('select * from user', function(error,results, fields){
            res.send(JSON.stringify(results));
            console.log('results', results);
            connection.release();

            if(error) throw error;
        })
    })
})

 

생성된 pool 을 mysql 과 연결한다.

query 함수를 이용하여 mysql 에 명령을 전달한다.

sql에서 데이터 request 가 온다면 아래와 같이 불러올 수 있다.

 

request.on('end', function(){
          var post = qs.parse(body);
          var title = post.title;
          var description = post.description;

          db.query(`insert into topic (title, description, created, author_id) 
          values (?, ?, NOW(), ?)`,
          [post.title, post.description, 1],
          function(error, result){
            if(error){
              throw error;
            }
            response.writeHead(302, {Location: `/?id=${result.insertId}`});
            response.end();
          });
      });
반응형

'Web > NodeJS' 카테고리의 다른 글

[NodeJS] Chatting Service -1-  (0) 2022.02.06
반응형
///////CONCURRENT SERVER.c///////////
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define SIZE sizeof(struct sockaddr_in)

int main(void)
{
	int sockfd_listen;
	int sockfd_connect;
	int client_len;
	
	char buff[80];
	//struct sockaddr_in server = {AF_INET, 5000, INADDR_ANY};
	struct sockaddr_in server,client;
	// server, client 소켓 정의 	


	bzero(&server, sizeof(server));//server 에 자신의 크기만큼 0 으로 clear
	server.sin_family = AF_INET; //IPv4
	server.sin_port = 5000; // 포트 설정 
	server.sin_addr.s_addr = inet_addr("192.168.56.128");
	
	printf("Server IP %s, Server Port : %u\n",inet_ntoa(server.sin_addr), server.sin_port);
	
	///////////////SOCKET///////////////////
	printf("skcket()\n");
	sockfd_listen =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //sockfd_listen = 3
	if(sockfd_listen < 0)
		printf("socket error\n");
	else
		printf("client sock%d\n",sockfd_listen);
	///////////////SOCKET///////////////////

	///////////////BIND/////////////////////
	//1. IPv4 address
	printf("bind()\n");
	if(bind(sockfd_listen, (struct sockaddr *)&server, SIZE))
		printf("bind error \n");
	///////////////BIND/////////////////////	

 	///////////////LISTEN///////////////////
	printf("listen()\n");
   	if(listen(sockfd_listen,5) == -1)
		printf("listen error \n");
 	///////////////LISTEN///////////////////

	
	while(1){
		bzero(&client, sizeof(client));
		client_len= sizeof(client);
		
 	///////////////ACCEPT////////////////////
		printf("wating for client\n");
		sockfd_connect = accept(sockfd_listen, (struct sockaddr *)&client, &client_len);
		//sockfd_connect = 4
		
		if(sockfd_connect < 0 )
			printf("accept error\n");
		else
			printf("sockfd connect %d\n",sockfd_connect);
		printf("accepted\n");
		printf("SERVER : Client IP : %s, Client Port : %u \n",inet_ntoa(client.sin_addr), 			ntohs(client.sin_port));
 	///////////////ACCEPT////////////////////
	
 	///////////////ACCEPT////////////////////

	//client 와 ACCEPT 하면 fork 하여 자식 프로세스와 통신 
		if(fork() == 0) { //child process
		
		//close
			close(sockfd_listen); // 3 close (parent)
			while(1){
				bzero(buff,sizeof(buff));
				recv(sockfd_connect, buff, sizeof(buff), 0 );
				printf("Server recv %s \n",buff);
				
				//"quit" exit
				if(strcmp(buff, "quit") == 0){//when BUFFER is a "quit" 
					printf("client exit \n");
					close(sockfd_connect); // 4 child process close
					exit(0); // child process exit
				}
				else	{	
					//fgets(buff, sizeof(buff), stdin); // can't chat is child , buff= hello --> "hello:server"
					strcat(buff, ":::SERVER"); // BUFFER 에 :SERVER 를 달아서 server 가 메시지를 받음을 확인
					send(sockfd_connect, buff, strlen(buff),0);
					continue; // goto 67 line (while)
				}
			}

			close(sockfd_connect); // 4
			exit(0); // child process exit
			
		}//end child
		
		//paraent process
		printf("close() sockfd_connect = %d\n", sockfd_connect); //4s
		close(sockfd_connect);

	}//end while
	
	//close(sockfd_listen);	
}

 

Server 의 특징 

  • Client 코드를 직접 배포

 

///////////CILENT.c///////////

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>

#define SIZE sizeof(struct sockaddr_in)

int main(void)
{
	int sockfd;
	//char send_c, recv_c;
	char message[80];
	
	struct sockaddr_in server ;
	
	bzero(&server, sizeof(server));//0 clear
	server.sin_family = AF_INET; //IPv4
	server.sin_port = 5000;
	//server.sin_addr = INADDR_ANY;
	server.sin_addr.s_addr = inet_addr("192.168.56.128");
	printf("Client IP %s, Client Port : %u\n",inet_ntoa(server.sin_addr), server.sin_port);
	
/////////SOCKET//////////
	printf("skcket()\n");
	sockfd =socket(AF_INET, SOCK_STREAM, 0);
/////////SOCKET//////////
	
/////////CONNECT//////////
	printf("connect()\n");
	connect(sockfd, (struct sockaddr *)&server, SIZE);
/////////CONNECT//////////

/////////SEND_LOOP////////
	while(1){//send -> rcv
		printf("client message: ");
		fgets(message, sizeof(message), stdin);
		send(sockfd,message,strlen(message)-1,0);//fgets include 'enter' space so, -1
		
		bzero(message,sizeof(message));
		recv(sockfd, message, sizeof(message), 0);
		printf("client recv: %s \n",message);
	}
/////////SEND_LOOP////////	
	
	printf("close()\n");
	close(sockfd);
	
}
//////////FORK_PRACTICE/////////

#include <stdio.h>
#include <sys/type.h>
#include <unistd.h>

int main(void){

	pid_t pid;
//pid 선언
	
	pid=fork();
// fork 하여 자식 프로세스 생성
	
	if(pid>0){// 부모 프로세스 일때
		printf("parent process pid : %d \n",getpid());
		printf("parent process ppid : %d \n",getppid());
		printf("parent process child id : %d \n",pid);
		sleep(30);
	else if(pid==0){//자식 프로세스 일때
		printf("child process pid : %d \n",getpid());
		printf("child process ppid : %d \n",getppid());
	}
	else{
		prinf("fork error\n");
	}
}
반응형

'Lecture > System Software' 카테고리의 다른 글

[시소프] 3.SIC, SIC/XE  (0) 2021.10.31
[시소프] 2.Machine Level  (0) 2021.10.26
[시소프]1. Integer, Float  (0) 2021.10.25
반응형

SIC

  • virtual 환경에서 작동

  • SIC/XE 에서 SIC 함수 사용가능하지만 역은 안됨

Memory

  • 1byte = 8bits
  • 3byte = 1word
    • 'r' 시 p값이 3 씩 증가
  • 전체 $2^{15}$ bytes

Register

  • 각 레지스터는 1word
  • A(0) : 기본적인 산술연산 저장
  • X(1) : 주소저장, 계산
  • L(2) : 함수로 JUMP 시 돌아올 주소 저장
  • PC(8) : 다음 실행 명령어 저장
  • SW(9) : 산술연산 결과상태 필드플래그 저장

Data Format

  • Integer : 1word , binary
  • Character : 1byte ASCII code

명령어 포맷 구성

opcode(8) + X(1) + Address(15) = 24bit

주소지정방식

  • X = 0 → 직접주소지정
    • TA = Address
  • X = 1 → 인덱스 주소 지정방식
    • TA = Address + (X)

명령어 타입

  1. LD(Load)
    1. LDA m : A ← (m)
  2. ST(Store)
    1. STA m : m ← (A)
  3. 산술연산
    1. ADD, SUB,...
  4. COMP
    1. COMP m : A와 B를 비교후 LT, GT, EQ 를 SW에 저장
    2. TIX m : X+1 과 비교, 저장
  5. 조건부 점프
    1. J m : PC ← m
    2. JLT m : PC ← m , if cc set to <
    3. JRT m
    4. JEQ m
  6. 서브루틴 링커
    1. JSUB m : L ← (PC), PC ← m
    2. RSUB : PC(L)
  7. I /O
    1. TD
    2. WD
    3. RD
  8. 저장소 정의
    1. CHARA BYTE C'A'
    2. FOUR WORD 4

SIC/XE

  • SIC 보다 전체 메모리가 크다 ($2^{20}$)

Register

  • B(3) : 주소 지정
  • S(4) : 범용 레지스터
  • T(5) : 범용 레지스터
  • F(6) : 실수연산 (2word)

Data Format

  • Floating Point 추가
  • S(1) EXP (11) Fraction(36)

Instruction Format

  • Format 1 (1byte)
    • opcode(1byte)
  • Format 2 (2byte)
    • opcode(1byte) + reg1(4bit) + reg2(4)
  • Format 3 (3byte)
    • opcode(6) nixbpe (6) disp (12)
    • e = 0
      • b=1, p=0 : Base relative : TA = B + disp
      • b=0, p=1 : PC relative : TA = PC + disp
      • b=0, p=0 : direct : TA = disp
  • Format 4 (4byte)
    • opcode(6) nixbpe(6) address(20)
    • e = 1
      • n=0, i=1 : immediate Addressing : TA값을 주소로 사용 않고, 그 자체로 값사용
      • n=1, i=0 : indirect Addressing : TA를 간접주소사용
      • n=0,i=0 , n=1,i=1 : Simple Addressing : TA로 메모리 접근
반응형

'Lecture > System Software' 카테고리의 다른 글

[시소프] 4. 서버, 클라이언트, fork()  (0) 2021.11.23
[시소프] 2.Machine Level  (0) 2021.10.26
[시소프]1. Integer, Float  (0) 2021.10.25

+ Recent posts