도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요, 상훈입니다.

 

■ Websocket (웹소켓)

- Websocket이란?
- Websocket과 socket.io
- Websocket, JavaScript
- Websocket, Socket.io

 

■ Websocket이란? / Websocket의 특징

  1. 서버(server)와 클라이언트(client)간의 특정 포트를 이용해 지속적인 실시간 양방향 통신 
  2. 실시간 통신이 필요한 경우에 사용
    ex) 실시간 스트리밍 방송, 채팅, 게임 등
  3. 일반 TCP Socket과 다른 점
    → 최초 접속 = 일반 Http Request를 통해 handshaking과정 거친다.
  4. 기존의 port : 80, 443으로 접속→ CORS적용, 인증 등을 유지 가능
  5. → 추가 방화벽을 열지 않고 통신이 가능함

■ 추가. 비동기(Http)통신을 웹소켓처럼 사용하면 지속적인 연결을 요청하기 때문에 과부하가 걸린다.

 

■ Websocket과 socket.io

  - WebSocketsocket.io 는 다르다.

→ WebSocket
  : 양방향 소통 프로토콜, socket.io : 양방향 통신을 위해 웹소켓 기술을 활용하는 라이브러리.
    ⇒ JavaScript & jQuery 의 관계

참고

 

■ 사용 방법 - JavaScript

웹소켓을 사용하려면 Web Socket 객체 생성을 해야한다.

→ 이 객체는 자동으로 서버와 연결을 열려고 할 것이다.

  1. 필수 파라미터 1개 : url
  2. 선택 파라미터 1개 : protocols
  3. ERROR : SECURITY_ERR ⇒ 포트 차단일 경우 발생
  • 한개의 프로토콜
 var exampleSocket 
   = new WebSocket("ws://www.example.com/socketserver", "protocolOne");

 

  • 여러개의 프로토콜
var exampleSocket
 = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);

 

  • 서버에 데이터 전송
    • 전송 가능한 데이터 유형 : String, Blob, ArrayBuffer
    • 바로 데이터를 전송하면 실패할 수 있기 때문에 onopen() 으로
exampleSocket.onopen = function (event) {
  exampleSocket.send("Here's some text that the server is urgently awaiting!");
};

 

  • 서버로부터 데이터 수신
    • 메세지가 수신되면 message 이벤트 ⇒ onmessage 함수로 전달된다.
  • exampleSocket.onmessage = function (event) {
      console.log(event.data);
    }
  • 연결 종료
    • 웹 소켓 사용 종료 시 close() 메소드를 호출하여 연결을 종료한다.
    exampleSocket.close();
    
    • 네트워크에 전달이 되지 않은 정보가 아직 남았을 수도 있으니, bufferedAmount Attribute를 조사하여 데이터를 검사하는 것도 좋다.
  • 고려사항 - 보안
    • 웹소켓은 혼합 연결 환경에 이용할 수 없다.
    • ex) HTTPS로 로드 된 페이지 → non-secure 웹소켓 연결 수립, non-secure 웹소켓 연결 → HTTPS로 로드 된 페이지

참고페이지 : MDN

 

 

■ 사용방법 - Node.js

Node.js에서 웹소켓을 구성하려면 ws 패키지를 사용해야 한다.

$ npm install ws

 

  1. 서버측
    • port: 3000 으로 웹소켓 서버를 연다.
const WebSocket = require('ws')
const wss = new WebSocket.Server({ port: 3000 })

wss.on('connection', ws => {
  ws.on('message', message => {
    console.log('received: %s', message)
  })
  ws.send('something')
})

 

  1. 클라이언트측
    • 마찬가지로 port:3000 으로 연결하고 데이터를 전송
const ws = new WebSocket('ws://localhost:3000')

ws.on('open', () => {
  ws.send('something')
})
ws.on('message', data => {
  console.log(data)
})

참고페이지 : 웹소켓

 

 

출처: 메시지 아이콘 제작자: Freepik - Flaticon

반응형

 

Canvas.js 를 사용하는 와중 특정한 조건에 의해 새로운 차트비동기로 재출력하는 상황,
아래와 같은 에러가 발생하였다.

 

 

이유인즉슨, 기존의 차트가 존재하기 때문에 새로운 차트를 적용할 수 없다는 것이다.

 

그렇기 때문에 기존의 차트를 제거하는 수순을 밟아야한다.

 const ChartName = new Chart(
        document.getElementById('generalList'),			// canvas의 id 호출
        ChartNameConfig								// Config로 기본 설정했던 변수 호출
      );
      ChartName.destroy()							// ★★destroy로 기존의 canvas를 제거
  }

destroy()new Chart 함수의 마지막에 작성한다.

 

 

 

https://pretagteam.com/question/canvas-is-already-in-use-chart-with-id-0-must-be-destroyed-before-the-canvas-can-be-reused-chatjs

 

pretagteam.com

 

해당 페이지 참고

반응형

 

Javascript로 select box 내의 option들을 특정 조건에 의해 함수를 호출하여 제거하려고 한다. 
검색 기능으로 사용하면 유용하다.

 

물론 select box 말고도 p, span, div...등등 부모-자식 관계의 태그들이라면 모두 가능하다.

 

Node . removeChild 를 사용한다.

const item_name = document.querySelector('#item_name')	// item_name이라는 부모 요소
while (item_name.firstChild) {		// 첫번째 자식 태그가 존재하면 무한 반복
      item_name.removeChild(item_name.firstChild);		// 첫번째 자식 태그를 제거한다. 
 }

 

item_name 이라는 id를 가진 태그를 querySelector로 가져온다.

가져온 태그 내 자식 태그가 1개 이상일 때 반복문이 실행된다.

그리고 removeChild를 통해 자식요소를 제거한다.

 

 

 

Node.removeChild() - Web APIs | MDN

The removeChild() method of the Node interface removes a child node from the DOM and returns the removed node.

developer.mozilla.org

 

반응형

 

querystring을 받아왔는데 JavaScript get 방식으로 값을 받아오는 방법

 

// Query String 데이터 출력
function searchParam(key) { // key를 매개변수로 받고, value를 리턴
		return new URLSearchParams(location.search).get(key)
}

함수로 생성해놓고 사용하는 것이 편합니다.

 // url =  www.example.com?page=12
 const page = searchParam('page')
 console.log(page)       // 12 출력

 

key: value 형태이다보니, key 값을 매개변수로 넘겨주어야 value가 출력됩니다.

반응형

 

 

 

부트스트랩 cdn을 사용하던 와중 해당 에러가 지속적으로 발생하였다.

이 문제는 아주 단순한 내용이다.

스크립트의 순서 때문.

 

이런식으로 boostrapjquery cdn을 삽입하였는데, 순서를 바꿔주자

 

 

그렇다면 새로고침을 해주어 콘솔창을 확인하면 에러가 사라졌음을 알 수 있다.

jQuery가 먼저오고, bootstrap이 그 다음에 와야 해당 에러가 발생하지 않는다.

 

이상입니다.

반응형

html <input> 태그 내에서 enter 를 입력 시 javascript로 원하는 이벤트를 발생시키는 방법

input 태그 내에

<input type="text" 
	onkeypress="if(window.event.keyCode==13){ function name() }"
    />

를 작성해주도록 한다.

 

enter = keyCode 13

반응형

 

 

PHPMailer를 통해 이메일을 송신하곤 했는데,

불편하기도 하고 읽기 불편해서 찾아보게 된 EmailJS. 

자바스크립트 기반으로 이메일을 보낼 수 있다.

parameter 를 통해 원하는 내용을 전달할 수 있어서 더 좋다. (역시 js)

Google에 검색하면 1순위로 나오는 웹사이트 (광고 아님)

emailjs

 

Send email from Javascript - no server code required | EmailJS

Send email directly from your client-side Javascript code – no server side code required. Add static or dynamic attachments, dynamic parameters, captcha code and more. Start with our free tier!

www.emailjs.com

 

이곳에서 회원가입 -> dashboard로 진행하면 된다.

 

form

회원가입 폼도 간단하다. 본인 email, 비밀번호만 설정하면 된다.

로그인시, 바로 대쉬보드로 이동하게 되는데, 

 

■ 필요사항

1. 서비스 생성
2. 템플릿 생성 + 템플릿-id
3. integration (과거 installation) 에서 init-code

 

 

1. 서비스 생성

Add New Service 클릭
원하는 항목 선택

 

원하는 이메일 서비스를 선택하면 되는데, 구글(Gmail)을 선택하였다.

 

Service ID는 원하는 아이디로 사용하는게 좋다. 회사명, 본인 이름 등..

Connect Account를 통해 Gmail과 연동 후 Create Service

 

Email Service 생성 완료

 

2. 템플릿 생성 + 템플릿-id

이제 템플릿을 생성하도록 한다.

확인을 잘 해주시고 각각의 항목에 삽입한다. 내용을 모두 작성하였으면 Save

 

그리고 Template ID 도 챙겨가자.

 

마지막.

■ 3. integration (과거 installation) 에서 init-code

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/emailjs-com@3/dist/email.min.js"></script>
<script type="text/javascript">
(function() {
emailjs.init("챙겨야할 init 코드");
})();
</script>

 

■ 실제 적용

저는 php로 데이터를 받아와 javascript이메일 송신하는 방식을 사용합니다.

<script type="text/javascript"
        src="https://cdn.jsdelivr.net/npm/emailjs-com@3/dist/email.min.js">
</script>
<script type="text/javascript">
    // init code 사용
    emailjs.init("3. 사용자_init_code");
    
    // parameter 설정
    const templateParams = {
        to_email: '<?=$requestedEmail?>',
        message_html: 'you have changed your password.',
        new_password: <?=$newPassword?> ,
    };
    
    // email 송신 과정
    emailjs.send('1.사용자id', '2.템플릿 id', templateParams)
        .then(function(response) {
            console.log('SUCCESS!', response.status, response.text)	 //success
        }, function(error) {
            console.log('FAILED...', error)		//fail
        });
</script>

이런식으로 사용하면 됩니다. 

파라미터에 값을 잘못넣거나 공란이 되면 에러개발자도구-콘솔에 출력이 되니, 확인하시면서 조율하면 됩니다.

promise.then() 으로 결과 출력 확인 가능 

 

■ 결과

메일이 잘 도착하였습니다.

 

EmailJS - DashBoard - Email History 에서도 확인하실 수 있습니다.

 

 

 

 

반응형

 

 

자바스크립트로 css 를 제어할 수 있습니다.

보고있는 화면의 크기에 따라 클래스를 추가하고, 제거할 수 있듯이 말이죠. 

대신 하나하나 클래스를 지정하거나 스타일을 지정해주어야합니다.

css 로는 @media ( width: 1000px ) { }  이런 식으로 작성합니다.

JavaScript 로는 matchMedia(`(max-width: 1000px)`) 메서드를 사용합니다.

화면 크기에 맞춰 변경되는 결과

 

■ 기본

<script>
	// 화면인식 992px 사이즈 조절
	const mediaViewContent = window.matchMedia(`(max-width: 992px)`)	// 1
	console.log(mediaViewContent)
    
    const viewChangeHandler = (mediaViewContent) => {  					// 3
    	//이곳에 원하는 이벤트 설정
    }
    
    mediaViewContent.addEventListener("change", viewChangeHandler)		// 2
</script>

이렇게 matchMedia( ) 메서드를 통해 화면이 변하는 것을 인지할 수 있는데, 해당 내용을 콘솔에 입력해보았습니다.

 

console.log(mediaViewContent)

콘솔창에 출력된 내용을 확인, max-width:992px 기준으로 작성이 되어있는 것을 확인할 수 있습니다.

 

■ 응용

MediaQuery를 다루려면 MediaQuery 내 match라는 녀석을 활용하면 편하다.

992px 이상이 되면 false, 미만이 되면 true가 되는데, 이를 이용하도록 한다. 
[기준 이상: false, 기준 미만: true ]

<script>
	if(mediaViewContent.matches === true){
    	// 992px보다 작아질 때 
	} else {
    	// 992px 보다 커질 때 (원상복구)
	}
</script>

이런식으로 사용 하면 되는데,

각각의 내용 안에 id.style.any = '' 를 지정해주면 된다.

 

■ 응용 - 예시)

<script>
const mediaViewContent = window.matchMedia(`(max-width: 992px)`)

const viewChangeHandler = (mediaViewContent) => {
    const moveToQnA = document.querySelector('#moveToQnA')
    const flexControlPannel = document.querySelector('#flexControlPannel')
    const moveToStatisticsList = document.querySelector('#moveToStatisticsList')

    if(mediaViewContent.matches === true){
        console.log('shrink')
        moveToQnA.classList.remove("col-5")
        moveToQnA.classList.remove("ml-5")
        moveToQnA.classList.add("mb-5")
        moveToQnA.style.width="100%"
        flexControlPannel.classList.remove("d-flex")
        flexControlPannel.classList.remove("justify-content-between")
        flexControlPannel.style.height="100%"
        moveToStatisticsList.classList.remove("col-5")
        moveToStatisticsList.style.width="100%"

    } else {
        console.log('release')
        moveToQnA.classList.add("col-5")
        moveToQnA.classList.add("ml-5")
        moveToQnA.classList.remove("mb-5")
        moveToQnA.style.width="48%"
        flexControlPannel.classList.add("d-flex")
        flexControlPannel.classList.add("justify-content-between")
        flexControlPannel.style.height="400px"
        moveToStatisticsList.classList.add("col-5")

    }
    
}
mediaViewContent.addEventListener("change", viewChangeHandler)
</script>

 

결과

 

 

이상입니다.

 

 

 

반응형

+ Recent posts