수업 정리

46일차 수업 정리(Ajax, WebPush)

Vita500cc 2020. 6. 12. 09:43

**Web Communication API

1. Ajax - XMLHttpRequest

    =>비 동기적으로 서버의 데이터를 받아오는 기술

    => HTML5에서는 기존의 기능에 몇가지를 추가하여 Ajax Level2라고 함

    => 전체페이지를 다시 로드하지 않고 서버의 데이터를 가지고 일부분만 업데이트하기 위해서 사용

  1) 사용순서

    => XMLHttpRequest 객체를 생성

    => 생성한 객체를 이용하여 요청을 생성 - open(전송방식, url, 비동기여부)

        - 전송방식 : 'GET', 'POST'

        - GET : 파라미터(클라이언트가 서버에게 넘겨주는 데이터)를 url 뒤에 붙여서 전송

                 (속도는 빠르지만 파라미터 길이에 제한이 있고 보안에 취약)

        - POST : 파라미터를 header에 숨겨서 전송하는 방식

                 (파라미터 길이에 제한이 없고, GET보다 보안이 우수)

        - 최근에는 조금더 명확하게 작업을 하기 위해 PUT과 DELETE도 추가

        - GET은 READ, POST는 INSERT, PUT은 UPDATE, DELETE는 DELETE 작업에 사용하도록 권장

        - URL은 데이터를 전송받을 URL

        - 비동기 여부는 기본적으로 비동기 방식으로 동작하는데 false를 설정하면 동기식으로 동작

    => 요청을 전송 - send(data)

        - data는 파라미터 - HTML5에서는 일반 데이터 이외에 FormData가 추가됨

    => 요청을 취소 - abort()

  2) 요청시 발생하는 이벤트

    => load : 응답을 받았을 때

    => loadstart, loadended, abort, error

    => progress : 응답을 받고 있는 도중 발생하는 이벤트

  3) 받아온 데이터

    => 이벤트 처리 함수의 매개변수로 처리

    => 매개변수.target.responseText - XML형식을 제외한 데이터

    => 매개변수.target.responseXML

   4) Form의 데이터를 전송

    => 최근에는 폼의 데이터를 전송하는 부분을 ajax로 처리하기도 함

        - 대표예시 : 덧글(게시판 글쓰기는 입력시 목록화면으로 전환, 댓글은 해당 페이지에 남고 덧글만 추가 하게 구현)

    => 폼의 데이터를 하나로 만들기

        - var 변수명 = new FormData(form객체);

    => 폼에 있지 않은 데이터를 추가

        - 변수명.append("이름", 데이터);

    => ajax 객체에 넣어서 전송

        - ajax객체.send(변수명); //서버에게 전달

  5) CORS

    => 이전의 ajax는 자신의 도메인에만 접근이 가능

    => 이전에는 외부 도메인의 ajax처리는 proxy를 만들어서 처리

    => jsonp 서비스를 구축하면 외부 도메인에서도 ajax로 직접 요청이 가능

        - 외부 도메인에 ajax요청을 직접하는 것을 Cross-Origin Resource Sharing이라고 함

    => Kakao Open API는 jsonp 서비스를 제공하기 때문에 ajax 요청을 직접하는 것이 가능

 

2. Web Push(Server Sent Events)

    => 서버가 클라이언트의 요청이 없는데 메시지를 전송하는 것

    => 스마트 폰 애플리케이션에서는 APNS(Apple Push Notification Service)나 FCM(Firebase Cloud Message)라고 함

    => 클라이언트 작업

  1) EventSource 객체 생성

    - var 변수명 = new EventSource("서버경로");

  2) message 이벤트 등록

    - 변수명.addEventListener("message", function(매개변수){ 매개변수.data : 서버가 보내준 데이터 });

 

3. WebSocket

    => Web에서 양방향 통신을 위한 Spec

    => http는 서버에게 클라이언트가 요청을 하고 서버가 클라이언트에게 데이터를 넘겨주면 통신이 종료

        - 계속해서 통신을 하고자하면 계속 연결을 요청해야 함

    => Ewb Socket은 한번 연결시 연결을 해제할 때 까지 계속 연결을 유지

        - 채팅같은 서비스에는 http통신 보다는 WebSocket을 이용하는 것이 효율적

    => WebSocket과 WebPush는 서버가 구현되어 있어야 사용이 가능

    => 작업 순서

        (1) 웹 소켓 객체 생성 : var 변수명 = new WebSocket("ws://서버주소");

        (2) 메시지 전송 : 변수명.send(메시지);

        (3) 이벤트 처리 : open(접속했을 때), close(접속을 해제할때), message(서버에서 메시지가 온 경우)

             - 서버에서 보내준 메시지는 message 이벤트 처리 함수의 매개변수.data

             - 변수명.addEventListener('message', function(event){  event.data:전송된 메시지  });

    => WebSocket 서버 구축

        - 채팅의 경우 클라이언트들을 저장할 List를 생성

        - open이벤트 발생시 클라이언트를 list에 저장

        - close이벤트 발생시 클라이언트를 list에서 제거

        - message 이벤트 발생시 list의 모든 클라이언트에게 메시지를 전송

 

**웹 채팅 만들기

1. websocket-api.jar 파일을 WEB-INF디렉토리의 lib 디렉토리에 복사

2. 서버 역할을 수행할 클래스를 java resource/src 디렉토리에 생성

    => 클래스며은 아무런 의미가 없음

import java.util.ArrayList;
import java.util.List;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

//주소 생성
//ws://192.168.0.200:9000/webfrontend0611/chat
@ServerEndpoint("/chat")
public class WebSocketServer {
	//클라이언트 목록을 저장할 List를 생성
	//Session이 클라이언트 1개
	private List<Session> list = 
		new ArrayList<>();
	
	//open 이벤트 처리
	@OnOpen
	public void onOpen(Session session) {
		//list에 클라이언트 추가
		list.add(session);
		System.out.println(
			list.size() + " 접속 중");
	}
	
	//접속 해제 이벤트 처리
	@OnClose
	public void onClose(Session session) {
		//세션에서 클라이언트 제거
		list.remove(session);
		System.out.println(
			list.size() + " 접속 중");
	}
	
	//메시지가 온 경우 이벤트 처리
	@OnMessage
	public void onMessage(
			String message, Session session) {
		//메시지를 list의 모든 클라이언트에게 전송
		for(Session s : list) {
			try {
				s.getBasicRemote().sendText(message);
			}catch(Exception e) {
				System.out.println(e.getMessage());
			}
		}
	}
	
}

3. chatting.html 생성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>채팅</title>
</head>
<body>
	닉네임<input type="text" 
		id="nickname" size="20"/><br />
	보내는 메시지<input type="text"
		id="message" size="50" />
	<input type="button" value="보내기"
		id="sendbtn" /><br />
	받은 메시지<textarea id="disp" 
		rows="20" cols="80"></textarea>
</body>

<script>
	//DOM 객체 찾아오기
	var nickname = 
		document.getElementById("nickname");
	var message = 
		document.getElementById("message");
	var sendbtn = 
		document.getElementById("sendbtn");
	var disp = 
		document.getElementById("disp");
	//웹 소켓 객체 생성
	var webSocket = new WebSocket(
		"ws://192.168.0.200:9000/webfrontend0611/chat");
	
	//연결되었을 때 수행할 내용
	webSocket.addEventListener(
		"open", function(event){
		//채팅은 새로운 메시지를 위에 출력	
		//disp.value = "접속에 성공\n" + disp.value;
		webSocket.send(nickname.value + "님 입장");
	});
	
	//메시지가 온 경우
	webSocket.addEventListener(
		"message", function(event){
		//채팅은 새로운 메시지를 위에 출력	
		disp.value = 
			event.data + "\n" + disp.value; 
	});
	
	//버튼 눌렀을 때 메시지 보내기
	sendbtn.addEventListener(
		"click", function(event){
		var m = nickname.value + ":" + 
			message.value;
		webSocket.send(m);
		message.value = '';
	});
	
	message.addEventListener(
			"keydown", function(event){
		var e = event || window.event;
		var keycode = ('which' in e) 
			? e.which : e.keyCode;
		if(keycode == 13){
			var m = nickname.value + ":" + 
				message.value;
			webSocket.send(m);
			message.value = '';
		}
	});
	
</script>
</html>

 

**모바일 웹

1. 구현 방식

  1) 하나의 페이지를 만들고 css를 이용해서 다르게 보이도록 만드는 방법(반응형 웹 디자인)

  2) 모바일 페이지를 별도로 만들어서 모바일에서 접속했을 때, 모바일 페이지를 보여줌

2. 모바일 기기의 접속

    => navigator 객체의 userAgent 속성 확인시 운영체제, 브라우저명을 확인가능. 이때 모바일 운영체제를 확인

        - Android는 스마트폰과 태블릿을 구분하지 않음

        - Apple은 iPhone과 iPad로 태블릿을 구분함

3. 모바일 페이지의 설정

    => viewport 메타 태그를 이용해서 설정

    => https://developer.android.com/guide/webapps/targeting에서 확인 가능 

        - <meta name="viewport" content="width=device-width, user-scalable=no"/>의 형태로 많이 사용

4. 회전 이벤트

    => 기기의 방향이 바뀌면 window객체에 orientationchane 이벤트가 발생하고 window객체의 orientation 속성을 조사하면 기기의 방향을 알수 있음

    => 0이면 수직, 90이면 수평, -90이면 오른쪽으로 수평

        - 기기를 반대방향 수직으로 세우게 되면 180이 리턴되어야 하는데 인식을 못함

5. 터치 이벤트 

    => touchstart, touchend, touchmove, touchenter, touchleave

    => touchcancel : 인터럽트가 발생됬을 때(ex - 터치중 전화 옴)

6. 스마트 폰 애플리케이션

  1) Web App

    => 모바일 웹 사이트를 만들어서 안드로이드의 크롬이나 iOS의 사파리를 이용하여 접속

        - 하나의 사이트만 만들면 모두 사용이 가능하고, 수정이 쉬움

        - 터치와 회전을 제외한 다른 센서를 사용할 수 없음

    => 모바일 페이지를 만들고 안드로이드나 iOS앱을 만든후 WebView를 이용해서 이 페이지를 출력하는 방법

        - 모든 페이지를 전부 WebView를 이용하는 것은 reject사유

  2) Native App

    => 안드로이드나 iOS의 공식 지원 언어를 이용해서 앱을 만드는 것

    => 장점 : 실행속도가 가장 빠르고, 기기의 모든 하드웨어를 사용할 수 있음

         단점 : 운영체제 별로 앱을 만들어야 하고, 지원하는 언어로만 앱 제작 가능

  3) Hybrid App

    => react-native, flutter, phonegap 라이브러리 : HTML, CSS, JavaScript로 애플리케이션 프로젝트 제작

    => 장점 : 각각의 운영체제에 맞게 빌드하여 앱을 생성해 줌, 이 방법은 센서도 어느정도 사용 가능

         단점 : 업데이트가 너무 자주 일어나고, 새로운 운영체제가 나오면 바로 사용 불가능

    => Unity3D(C#) unreal(C++)과 같은 프레임워크 이용 : 프로그램 작성방식은 위와 유사(그래픽 구현에 특화)

 

**lazy loading

    => 지연 로딩

    => 객체 지향에는 지연생성이라는 개념이 있음

    => 처음부터 로딩하거나 생성하지 말고 필요할 때 로딩하거나 생성

    => 서버는 초기 구동시간이 오래걸리더라도 전부 로딩해 놓는 것이 좋음

         클라이언트는 처음에 필요한 것만 가지고 로딩을 하고 다른 자원은 필요할 때 로딩하는 것이 좋음

 

 

Tip!

1. 비밀번호 : 64자 이상(암호화)

2. 파일저장 : 경로를 저장(문자열(100자이상))