aboutsummaryrefslogtreecommitdiff
path: root/files/ko/websockets/writing_websocket_client_applications/index.html
blob: e7826d8595ef7524758ae556fb28ded203ec4034 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
---
title: WebSocket을 이용하여 클라이언트 애플리케이션 작성하기
slug: WebSockets/Writing_WebSocket_client_applications
tags:
  - 가이드
  - 네트워킹
  - 예제
  - 웹소켓
  - 웹소켓API
  - 클라이언트
translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications
---
<p>WebSocket은 ws 프로토콜을 기반으로 클라이언트와 서버 사이에 지속적인 완전 양방향 연결 스트림을 만들어 주는 기술입니다. 일반적인 웹소켓 클라이언트는 사용자의 브라우저일 것이지만, 그렇다고 해서 이 프로토콜이 플랫폼에 종속적이지는 않습니다.</p>

<div class="note"><strong>Note:</strong> 우리에게는 작동하는 chat/server 시스템 예제 코드 조각이 있습니다. 이는 우리의 인프라가 WebSocket 예제들을 제대로 호스팅할 수 있는 환경이 되면 공유할 것입니다.</div>

<p>{{AvailableInWorkers}}</p>

<h2 id="WebSocket_객체_생성하기">WebSocket 객체 생성하기</h2>

<p>WebSocket 프로토콜을 사용하여 통신하기 위해서는 <code><a href="/en/WebSockets/WebSockets_reference/WebSocket" title="en/WebSockets/WebSockets reference/WebSocket">WebSocket</a></code>객체를 생성해야 합니다. 이 객체는 자동으로 서버로의 연결을 열려고 할 것입니다.</p>

<p>WebSocket 생성자는 하나의 필수 파라미터와 하나의 선택 파라미터를 받습니다.</p>

<pre class="notranslate">WebSocket WebSocket(
  in DOMString url,
  in optional DOMString protocols
);
</pre>

<dl>
 <dt><code>url</code></dt>
 <dd>연결할 URL으로, 이것은 WebSocket 서버가 응답할 URL이어야 합니다.</dd>
 <dt><code>protocols</code> {{ optional_inline() }}</dt>
 <dd>하나의 프로토콜 문자열, 또는 프로토콜 문자열의 배열입니다. 이 문자열들은 서브 프로토콜을 지정하는데 사용되어, 하나의 서버가 여러 개의 WebSocket 서브 프로토콜을 구현할 수 있도록 해줍니다. 예를 들어, 하나의 서버가 처리하는 상호작용이 지정된 <code>protocols</code>에 따라 달라지도록 할 수 있습니다. 만약 프로토콜 문자열을 지정하지 않으면 빈 문자열을 넣은 것으로 간주됩니다.</dd>
</dl>

<p>생성자는 예외를 발생시킬 수 있습니다:</p>

<dl>
 <dt><code>SECURITY_ERR</code></dt>
 <dd>접속을 시도하고 있는 포트가 차단되었습니다.</dd>
</dl>

<dl>
</dl>

<h3 id="연결_에러">연결 에러</h3>

<p>만약 연결 시도 중 에러가 발생하면, 먼저 "error"란 이름의 이벤트가 <code><a href="/en/WebSockets/WebSockets_reference/WebSocket" title="WebSocket">WebSocket</a></code> 오브젝트로 전달되고, 그로 인해 <code>onerror</code> 핸들러가 실행됩니다. 그 후에 연결이 종료되는 이유를 가리키는 <a href="/en/WebSockets/WebSockets_reference/CloseEvent" title="CloseEvent"><code>CloseEvent</code></a> 이벤트가 <code><a href="/en/WebSockets/WebSockets_reference/WebSocket" title="WebSocket">WebSocket</a></code> 오브젝트로 전달되고, 그로 인해 <code>onclose</code> 핸들러가 실행됩니다.</p>

<p>Firefox 11부터는 보통 에러 메세지에 대한 설명이 Mozillia 플랫폼의 콘솔에 표시되며, <code><a href="/en/WebSockets/WebSockets_reference/CloseEvent" title="CloseEvent">CloseEvent</a></code>로부터는 <a class="external" href="http://tools.ietf.org/html/rfc6455#section-7.4" title="RFC 6455 Section 7.4">RFC 6455, Section 7.4</a>에 정의되어 있는 연결 종료 코드를 받게 됩니다.</p>

<h3 id="예제">예제</h3>

<p>이 간단한 예제는 새 웹소켓 오브젝트를 생성하여 <code><span class="nowiki">ws://www.example.com/socketserver </span></code><span class="nowiki">서버에 접속하는</span>것을 보여줍니다. 이 예제에서는 커스텀 프로토콜인 "protocolOne" 을 리퀘스트에 같이 지정합니다. (이 프로토콜을 지정하는 부분은 생략될 수 있습니다.)</p>

<pre class="brush: js notranslate">var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
</pre>

<p>반환된 <code>exampleSocket </code>오브젝트의<code> exampleSocket</code>.<code>readyState </code>값은<code> CONNECTING </code>입니다.<code> readyState</code> 값은 연결이 수립되어 데이터가 전송 가능한 상태가 되면 <code>OPEN</code> 으로 변경됩니다.</p>

<p>만약 여러개의 프로토콜을 유연하게 대응할 수 있는 구조를 가지고 있다면, 연결 시에 배열을 통해 프로토콜의 목록을 지정할 수 있습니다.</p>

<pre class="brush: js notranslate">var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
</pre>

<p>연결이 수립되면(<code>readyState</code> 가 <code>OPEN</code> 이 되었을 때<code>), exampleSocket.protocol </code>값을 조사하여 서버가 어떤 프로토콜을 선택했는지 알아낼 수 있습니다.</p>

<p>위의 예제에서 ws 는 http 를 대체합니다. 비슷하게 wss 는 https 를 대체합니다. 웹소켓 연결은 HTTP 업그레이드 메카니즘에 의해 수행되기 때문에 HTTP 서버 주소 지정에 대한 프로토콜 업그레이드 요청은 암시적입니다.  (<code><span class="nowiki">ws://www.example.com</span></code> 또는 <code><span class="nowiki">wss://www.example.com</span></code>. 같이)</p>

<h2 id="서버에_데이터_전송하기">서버에 데이터 전송하기</h2>

<p>한번 연결이 수립되면 이제부터는 서버로 데이터를 전송할 수 있습니다. 이것을 하기 위해서는 단순히 <code>WebSocket</code> 오브젝트의 <a href="/en/WebSockets/WebSockets_reference/WebSocket#send()" title="en/WebSockets/WebSockets reference/WebSocket#send()"><code>send()</code></a> 호출하여 보내고 싶은 메세지를 지정하기만 하면 됩니다.:</p>

<pre class="brush: js notranslate">exampleSocket.send("Here's some text that the server is urgently awaiting!");
</pre>

<p>보낼 수 있는 데이터는 String , {{ domxref("Blob") }},  또는 <code><a href="/en/JavaScript_typed_arrays/ArrayBuffer" title="en/JavaScript typed arrays/ArrayBuffer">ArrayBuffer</a> </code>입니다.</p>

<div class="note"><strong>Note:</strong> 버전 11 아래의 파이어폭스는 String 데이터 전송만을 지원합니다.</div>

<p>연결을 맺는것은 비동기 작업이고 실패하기 쉬운 작업이기 때문에, WebSocket 오브젝트를 생성하자마자  <code>send()</code> 로 데이터 전송을 시도하는것은 성공하지 않을 가능성이 있습니다. 우리는 연결이 수립된 이후에만 데이터를 전송하도록 하기 위해 <code>onopen</code> 핸들러를 정의하고, 이 위에서 작업합니다.</p>

<pre class="brush: js notranslate">exampleSocket.onopen = function (event) {
  exampleSocket.send("Here's some text that the server is urgently awaiting!");
};
</pre>

<h3 id="데이터_전송에_JSON_사용하기">데이터 전송에 JSON 사용하기</h3>

<p><a href="/en/JSON" title="en/JSON">JSON</a> 을 사용하면 서버에 복잡한 데이터를 편리하게 보낼 수 있습니다. 예를 들어, 채팅 프로그램이 서버와 JSON으로 캡슐화된 패킷 데이터를 주고받는 프로토콜을 구현한것을 상상해 볼 수 있습니다.:</p>

<pre class="brush: js notranslate">// Send text to all users through the server
function sendText() {
  // Construct a msg object containing the data the server needs to process the message from the chat client.
  var msg = {
    type: "message",
    text: document.getElementById("text").value,
    id:   clientID,
    date: Date.now()
  };

  // Send the msg object as a JSON-formatted string.
  exampleSocket.send(JSON.stringify(msg));

  // Blank the text input element, ready to receive the next line of text from the user.
  document.getElementById("text").value = "";
}
</pre>

<h2 id="서버로부터_데이터_수신하기">서버로부터 데이터 수신하기</h2>

<p>WebSockets는 event-driven API 입니다; 메세지가 수신되면 "message" 이벤트가 <code>onmessage</code> 함수로 전달되게 됩니다. 아래와 같은 코드를 작성하여 수신되는 데이터를 받아볼 수 있습니다.:</p>

<pre class="brush: js notranslate">exampleSocket.onmessage = function (event) {
  console.log(event.data);
}
</pre>

<h3 id="JSON_오브젝트를_받아서_처리하기">JSON 오브젝트를 받아서 처리하기</h3>

<p>상단의 {{ anch("데이터 전송에 JSON 사용하기") }} 에서 작업한 코드와 연관되는 클라이언트를 생각해 봅시다. 클라이언트에서 받을 수 있는 패킷들의 목록은 다음과 같을 것 입니다.:</p>

<ul>
 <li>로그인 핸드쉐이크</li>
 <li>메세지 텍스트</li>
 <li>유저 목록 업데이트</li>
</ul>

<p>위의 메세지들을 받아서 처리하는 코드는 아래와 같을 것 입니다.:</p>

<pre class="brush: js notranslate">exampleSocket.onmessage = function(event) {
  var f = document.getElementById("chatbox").contentDocument;
  var text = "";
  var msg = JSON.parse(event.data);
  var time = new Date(msg.date);
  var timeStr = time.toLocaleTimeString();

  switch(msg.type) {
    case "id":
      clientID = msg.id;
      setUsername();
      break;
    case "username":
      text = "&lt;b&gt;User &lt;em&gt;" + msg.name + "&lt;/em&gt; signed in at " + timeStr + "&lt;/b&gt;&lt;br&gt;";
      break;
    case "message":
      text = "(" + timeStr + ") &lt;b&gt;" + msg.name + "&lt;/b&gt;: " + msg.text + "&lt;br&gt;";
      break;
    case "rejectusername":
      text = "&lt;b&gt;Your username has been set to &lt;em&gt;" + msg.name + "&lt;/em&gt; because the name you chose is in use.&lt;/b&gt;&lt;br&gt;"
      break;
    case "userlist":
      var ul = "";
      for (i=0; i &lt; msg.users.length; i++) {
        ul += msg.users[i] + "&lt;br&gt;";
      }
      document.getElementById("userlistbox").innerHTML = ul;
      break;
  }

  if (text.length) {
    f.write(text);
    document.getElementById("chatbox").contentWindow.scrollByPages(1);
  }
};
</pre>

<p>여기서 우리는 <a href="/en/JavaScript/Reference/Global_Objects/JSON/parse" title="en/JavaScript/Reference/Global Objects/JSON/parse"><code>JSON.parse()</code></a> 를 통해 JSON 오브젝트를 자바스크립트 오브젝트로 변환합니다. 그 다음 콘텐츠에 따라 분기하고 처리하는 로직을 가집니다.</p>

<h3 id="Text_data_format">Text data format</h3>

<p>웹소켓을 통해 전달되는 텍스트들은 UTF-8 포멧을 가집니다.</p>

<p>Gecko 9.0 {{ geckoRelease("9.0") }} 먼저 버전들은 유효한 UTF-8 텍스트가 아닌 문자가 들어올 경우 연결이 종료되었습니다. 지금은 이 값들을 정상적으로 허용합니다.</p>

<h2 id="연결을_종료하기">연결을 종료하기</h2>

<p><code><font face="Open Sans, Arial, sans-serif">웹 소켓 사용을 마쳤다면 </font><a href="/en/WebSockets/WebSockets_reference/WebSocket#close()" title="en/WebSockets/WebSockets reference/WebSocket#close()">close()</a> 메소드를 호출해 연결을 종료합니다.</code>:</p>

<pre class="brush: js notranslate">exampleSocket.close();
</pre>

<p>연결을 닫아버리기 전에 <code>bufferedAmount </code>어트리뷰트를 조사하여 아직 네트워크에 전달되지 않은 데이터가 있는지 검사하는것도 좋은 방법입니다.</p>

<h2 id="보안에_대한_고려_사항">보안에 대한 고려 사항</h2>

<p>웹소켓은 혼합된 연결 환경에서 이용되어서는안됩니다. 예를들어 HTTPS를 이용해 로드된 페이지에서 non-secure 웹소켓 연결을 수립하는것(또는 반대) 처럼 말입니다. 몇몇 브라우저들은 이를 강제로 금지하고 있습니다. 파이어폭스 버전 8이상도 이를 금지합니다.</p>

<p>{{ languages ( {"zh-tw": "zh_tw/WebSockets/Writing_WebSocket_client_applications"} ) }}</p>