메뉴얼 웹은 어떻게 연결해야 하나요?
페이지 정보
본문
브라우저(웹)에서 메시지 브릿지 서버에 연결하는 방법은 아주 간단합니다.
딱 한 줄로 WebSocket을 만들고, 이벤트만 달아주면 됩니다.
const ws = new WebSocket("wss://designonex.com:14147/?group=도메인");
꼭 알아야 하는 핵심 3가지
1. wss:// 로 연결해야 함
SSL 인증서가 적용된 WebSocket 서버입니다. 그냥 ws:// 로는 연결 안 됩니다.
메시지 브릿지는 HTTP와 HTTPS 프로토콜을 모두 지원합니다.
사용자 사이트가 어떤 방식으로 서비스되고 있든, 동일한 방식으로 연결하여 사용할 수 있습니다.
주의 안내
- 사이트가 HTTP라도, WebSocket은 반드시 wss:// 를 사용해야 합니다.
(보안상 안전하며, 모든 환경에서 일관된 연결을 보장하기 위함입니다.) - 서버 설정이나 브라우저 호환성 걱정 없이 바로 적용할 수 있습니다.
2. group 값 필수
서버에서 group= 값이 없으면 접속을 막습니다.
즉, 무조건 다음 형태로 접속해야 합니다.
wss://서버주소:포트/?group=그룹명
3. JSON으로 메시지를 보내는 것이 좋음
메시지 브릿지는 모든 통신 메시지를 JSON 형식으로 주고받는 방식을 권장합니다.
JSON은 웹 표준 구조이기 때문에 이점이 있습니다.
구조화된 데이터 전달
여러 종류의 메시지를 구분하기 쉬움
확장성(Extensibility) 우수
대부분의 언어에서 기본 지원
{
"type": "message",
"id": "user123",
"message": "Hello",
"time": "2025-11-11 17:20:00"
}
대충 이해하셨나요? 이젠 샘플 소스를 분석하겠습니다.
// ---------------------------
// 기본 설정
// ---------------------------
const group = window.location.hostname;
const myId = "user_" + Math.floor(Math.random() * 9999);
const extValue = "ext_example";
const extValue1 = "ext1_example";
let ws = null;
let reconnectTimer = null;
// ---------------------------
// 로그 출력 함수
// ---------------------------
function log(msg) {
const box = document.getElementById("log");
box.textContent += msg + "\n";
box.scrollTop = box.scrollHeight;
}
// ---------------------------
// WebSocket 연결 함수
// ---------------------------
function connectWebSocket() {
log("Connecting...");
ws = new WebSocket(
"wss://designonex.com:14147/?group=" + encodeURIComponent(group)
);
ws.onopen = () => {
log("[연결 성공]");
if (reconnectTimer) clearTimeout(reconnectTimer);
};
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
log("[받음] " + JSON.stringify(data));
} catch {
log("[받음] " + event.data);
}
};
ws.onerror = (e) => {
log("[오류] " + e);
};
ws.onclose = () => {
log("[연결 종료] 재연결 시도 예정...");
reconnectTimer = setTimeout(() => {
connectWebSocket();
}, 3000); // 3초 후 자동 재접속
};
}
// ---------------------------
// 페이지 로드 시 자동 연결
// ---------------------------
document.addEventListener("DOMContentLoaded", connectWebSocket);
// ---------------------------
// 모바일 화면 복귀 시 재접속
// ---------------------------
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
if (!ws || ws.readyState === WebSocket.CLOSED) {
log("[화면 복귀] 자동 재접속");
connectWebSocket();
}
}
});
// ---------------------------
// 메시지 전송
// ---------------------------
document.getElementById("sendBtn").onclick = () => {
if (!ws || ws.readyState !== WebSocket.OPEN) {
log("[오류] WebSocket이 연결되지 않았습니다.");
return;
}
const msg = document.getElementById("msg").value;
if (!msg) return;
const data = {
type: "message",
id: myId,
ext: extValue,
ext1: extValue1,
message: msg
};
ws.send(JSON.stringify(data));
log("[보냄] " + JSON.stringify(data));
document.getElementById("msg").value = "";
};
const group = window.location.hostname;
- group이라는 상자(변수)에 지금 보고 있는 웹사이트의 도메인을 넣어요.
- 예: 네가 https://designonex.com/을 보고 있으면 group에 "designonex.com"이 들어가요.
const myId = "user_" + Math.floor(Math.random() * 9999);
- myId라는 상자에 내 이름표를 만들어 넣어요.
- Math.random() * 9999는 0부터 9999 사이의 숫자를 랜덤으로 만들고, Math.floor는 소수점 아래를 잘라서 정수로 만들어요.
- 결과 예: "user_482" 또는 "user_9031" 같은 값이 생겨요.
const extValue = "ext_example";
const extValue1 = "ext1_example";
- extValue와 extValue1은 추가로 보내고 싶은 보조 정보를 미리 정해 둔 거예요.
- 예를 들어 누가 보내는지 더 설명하거나, 어떤 방식을 쓴다는 표시를 넣을 때 쓸 수 있어요.
- 지금은 단순히 예시 문자열이 들어있어요.
let ws = null;
let reconnectTimer = null;
- ws는 WebSocket(웹소켓) 연결을 담을 상자예요. 아직 연결을 만들지 않았으니 null로 비워 놨어요.
- reconnectTimer는 재연결을 예약한 타이머를 기억해두려고 만든 상자예요. 아직 예약 안 했으니 null이에요.
// ---------------------------
// 로그 출력 함수
// ---------------------------
function log(msg) {
const box = document.getElementById("log");
box.textContent += msg + "\n";
box.scrollTop = box.scrollHeight;
}
- log라는 **함수(동작 묶음)**을 만들었어요. 이건 화면에 글자를 쌓아 보여주는 역할이에요.
- msg는 함수에 넣어주는 메시지(문장)예요.
- document.getElementById("log")는 HTML에서 id="log"인 상자(글이 보이는 곳)를 찾아요.
- box.textContent += msg + "\n"; 는 기존 글 맨 끝에 새 글을 줄바꿈과 함께 붙여요.
- box.scrollTop = box.scrollHeight; 는 글이 많아져도 자동으로 맨 아래(최근 글)로 스크롤을 내려줘요.
// ---------------------------
// WebSocket 연결 함수
// ---------------------------
function connectWebSocket() {
log("Connecting...");
ws = new WebSocket(
"wss://designonex.com:14147/?group=" + encodeURIComponent(group)
);
ws.onopen = () => {
log("[연결 성공]");
if (reconnectTimer) clearTimeout(reconnectTimer);
};
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
log("[받음] " + JSON.stringify(data));
} catch {
log("[받음] " + event.data);
}
};
ws.onerror = (e) => {
log("[오류] " + e);
};
ws.onclose = () => {
log("[연결 종료] 재연결 시도 예정...");
reconnectTimer = setTimeout(() => {
connectWebSocket();
}, 3000); // 3초 후 자동 재접속
};
}
이 큰 덩어리는 서버와 연결하고, 연결 중/연결 후에 무슨 일을 할지 정하는 함수예요. 하나씩 살펴볼게요.
- function connectWebSocket() { ... }
설명: connectWebSocket이라는 이름의 작업(함수)을 만들어요. 이걸 부르면 그 안에 있는 일이 차례대로 실행돼요. - log("Connecting...");
설명: 화면에 “Connecting...” 이라는 글을 남겨요. (사용자에게 지금 연결 시도 중임을 알려줘요.)
ws = new WebSocket(
"wss://designonex.com:14147/?group=" + encodeURIComponent(group)
);
- 여기서 실제로 서버에 연결 시도를 해요. new WebSocket(...)이 바로 연결을 만드는 한 줄이에요.
- "wss://..."는 암호화된 웹소켓 주소예요. ?group=...은 어느 그룹으로 들어갈지 알려주는 주문 같은 거예요.
- encodeURIComponent(group)는 group에 한글이나 특수문자가 있을 때 안전하게 바꿔주는 장치예요.
- 연결이 성공하면 ws 상자에 연결 정보(전화선 같은 것)가 들어갑니다.
ws.onopen = () => {
log("[연결 성공]");
if (reconnectTimer) clearTimeout(reconnectTimer);
};
- ws.onopen은 연결이 성공했을 때 자동으로 불리는 부분이에요.
- log("[연결 성공]");는 화면에 연결되었다고 보여줘요.
- if (reconnectTimer) clearTimeout(reconnectTimer);는 혹시 전에 재연결 예약(타이머)을 해놨다면 취소하라는 뜻이에요. 이미 연결됐으니 더 이상 재접속을 시도할 필요가 없죠.
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
log("[받음] " + JSON.stringify(data));
} catch {
log("[받음] " + event.data);
}
};
- ws.onmessage는 서버나 다른 사용자로부터 메시지를 받을 때 자동으로 실행돼요.
- event.data 안에 실제 메시지가 있어요(대부분 문자열).
- try { JSON.parse(...) } 부분은 "이 문자열이 JSON(오브젝트 형태)이면 예쁘게 보여주고, 아니면 그냥 텍스트로 보여줘"라는 뜻이에요.
- catch { ... }는 JSON으로 못 바꾸면 그냥 그대로 보여주라는 안전장치예요.
ws.onerror = (e) => {
log("[오류] " + e);
};
- ws.onerror는 웹소켓에서 문제가 생겼을 때 알려줘요.
- 보통은 콘솔에 더 많은 정보가 나오지만, 화면에는 간단히 [오류]를 보여줍니다.
ws.onclose = () => {
log("[연결 종료] 재연결 시도 예정...");
reconnectTimer = setTimeout(() => {
connectWebSocket();
}, 3000); // 3초 후 자동 재접속
};
- ws.onclose는 연결이 끊겼을 때 자동으로 실행돼요.
- 먼저 화면에 연결이 끊겼다고 알리고, 3초 후에 다시 연결 시도를 하도록 예약합니다.
- setTimeout(...)은 시간을 두고 한 번 실행하게 예약하는 함수예요. 여기서는 3000밀리초 = 3초 후에 connectWebSocket()을 다시 부르겠다는 뜻이에요.
- 예약을 reconnectTimer에 저장하는 이유는, 나중에 연결 성공 시 이 예약을 취소하기 위해서예요 (clearTimeout).
// ---------------------------
// 페이지 로드 시 자동 연결
// ---------------------------
document.addEventListener("DOMContentLoaded", connectWebSocket);
- 이 코드는 웹페이지가 모두 준비되면(DOMContentLoaded) connectWebSocket 함수를 자동으로 실행하라고 말해요.
- 즉, 페이지를 열면 자동으로 서버에 연결을 시도해요.
// ---------------------------
// 모바일 화면 복귀 시 재접속
// ---------------------------
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
if (!ws || ws.readyState === WebSocket.CLOSED) {
log("[화면 복귀] 자동 재접속");
connectWebSocket();
}
}
});
- visibilitychange 이벤트는 "지금 이 탭(또는 앱 화면)이 보이는 상태로 바뀌었는가?"를 알려줘요.
예: 사용자가 다른 탭으로 갔다가 돌아오면 이 이벤트가 발생해요. - document.visibilityState === "visible"이면 화면이 다시 보이는 상태예요(복귀한 것).
- 안에 if (!ws || ws.readyState === WebSocket.CLOSED)는 "아직 연결이 없거나, 연결이 이미 종료(CLOSED)된 상태라면"이라는 뜻이에요.
- 이 조건이면 화면 복귀 시 자동으로 다시 연결을 시도합니다.
// ---------------------------
// 메시지 전송
// ---------------------------
document.getElementById("sendBtn").onclick = () => {
if (!ws || ws.readyState !== WebSocket.OPEN) {
log("[오류] WebSocket이 연결되지 않았습니다.");
return;
}
const msg = document.getElementById("msg").value;
if (!msg) return;
const data = {
type: "message",
id: myId,
ext: extValue,
ext1: extValue1,
message: msg
};
ws.send(JSON.stringify(data));
log("[보냄] " + JSON.stringify(data));
document.getElementById("msg").value = "";
};
- 이 부분은 전송 버튼(sendBtn)을 눌렀을 때 실행되는 동작이에요.
- 하나씩 설명할게요:
document.getElementById("sendBtn").onclick = () => { ... }
HTML에서 id="sendBtn"인 버튼을 찾아서, 그 버튼을 클릭하면 { ... } 안의 일을 하라고 약속해요.
if (!ws || ws.readyState !== WebSocket.OPEN) {
log("[오류] WebSocket이 연결되지 않았습니다.");
return;
}
- 먼저 웹소켓이 있는지(!ws가 아니어야 함)와 열려 있는 상태인지(readyState === WebSocket.OPEN)를 확인해요.
- 연결이 없으면 [오류]를 보여주고 더 이상 진행하지 않아요. (return)
const msg = document.getElementById("msg").value;
if (!msg) return;
- id="msg"인 입력창에서 사용자가 쓴 글(값)을 가져옵니다.
- 내용이 비어있으면 아무것도 보내지 않아요.
const data = {
type: "message",
id: myId,
ext: extValue,
ext1: extValue1,
message: msg
};
- 보낼 데이터를 객체 형태로 만들어요.
- type은 메시지 종류를 표시해요(여기선 "message").
- id는 위에서 만든 내 이름표(myId)를 넣어요.
- ext와 ext1는 추가 정보(설정한 값)를 넣어요.
- message는 실제로 보내고 싶은 글(msg)이에요.
ws.send(JSON.stringify(data));
log("[보냄] " + JSON.stringify(data));
- JSON.stringify(data)는 객체를 문자열로 바꿔줘요. 서버는 보통 문자열(특히 JSON)으로 주고받기를 좋아해요.
- ws.send(...)는 그 문자열을 서버로 보내는 실제 행동이에요.
- 보낸 내용을 화면에도 [보냄]으로 보여줘서 확인할 수 있어요.
document.getElementById("msg").value = "";
- 메시지를 보낸 뒤 입력창을 비워서 다음 메시지를 쉽게 쓸 수 있게 해요.
저희가 제공하는 기본 채팅 샘플 소스는 단순히 기능 구현 예제에 그치지 않습니다.
이 소스를 충분히 이해하고 활용하시면, 고객사 요구에 맞춘 맞춤형 기능 확장이 훨씬 수월해집니다.
- 핵심 구조 이해 → 빠른 확장: 연결, 메시지 송수신, 재연결 등 필수 로직이 이미 구현되어 있어, 추가 기능을 덧붙이는 과정이 단순하고 효율적입니다.
- 커스터마이징 용이: 스크립트, AJAX, UI 요소 등 필요한 기능을 자유롭게 확장할 수 있어, 고객 맞춤형 솔루션 개발에 최적화되어 있습니다.
- 개발 시간 절감 → 비용 효율성: 기본 로직을 이해한 상태에서 확장하면, 처음부터 전체를 새로 개발하는 것보다 훨씬 빠르고 안정적으로 프로젝트를 완성할 수 있습니다.
즉, 이 샘플은 단순 테스트용이 아니라, 실무에서 바로 응용할 수 있는 실전용 기반입니다.
기본 로직을 이해하는 순간, 여러분의 프로젝트에 맞는 맞춤형 확장 개발이 자연스럽게 가능해집니다.
추천0 비추천0
댓글목록
등록된 댓글이 없습니다.
