채널 API와 한도
room.plugin 채널로 실시간 데이터를 주고받는 함수, 값 형식, 저장과 전송 한도의 정본이에요.
마지막 수정 2026년 10월 19일
채널(room.plugin)은 같은 채팅방에 있는 사람끼리, 또는 내 서버와 채팅방 사이에 채팅 메시지가 아닌 데이터를 실시간으로 주고받는 통로예요. 이 문서는 함수·값 형식·한도의 정본이에요. 흐름은 실시간 데이터 주고받기, 서버에서 보내는 방법은 서버 REST API를 보세요.
room.plugin
| 이름 | 설명 |
|---|---|
room.plugin.add(channel) |
채널 객체를 돌려줘요. 같은 이름으로 다시 부르면 같은 객체를 돌려줘요 |
room.plugin.TO_ALL |
0. 받은 데이터의 type이 이 값이면 모두에게 보낸 것 |
room.plugin.ONLY_ME |
1. 받은 데이터의 type이 이 값이면 나에게만 보낸 것 |
채널 이름은 채팅방 안에서 겹치지 않게 정해요. 저장(save)까지 쓰려면 영문·숫자로 시작하고 영문·숫자·_·-만 쓴 64자 이하여야 해요.
U.chat('*').on('after.create#dice', function (room) {
if (room.id !== 'my-room') return;
var ch = room.plugin.add('dice');
ch.onReceived(function (room, data) {
room.print(data.user.nick + '님의 주사위: ' + data.data[0]);
});
ch.addParser(function (args) {
ch.send([Math.floor(Math.random() * 6) + 1]);
});
});
채널 객체
| 함수 | 인자 | 설명 |
|---|---|---|
send(values) |
값 배열 | 채팅방의 모두에게 보내요. 보낸 나도 받아요 |
sendTo(nick, values) |
닉네임, 값 배열 | 한 사람에게만 보내요. 내 닉네임을 대상으로 하지 않으면 나는 받지 않아요. 대상이 없으면 아무 일도 일어나지 않아요(오류 없음) |
save(values) |
값 배열 | 마지막 상태를 서버에 저장해요. 부관리자 이상. 아래 저장 |
clear() |
— | 이 채널의 저장값을 지워요. 부관리자 이상 |
onReceived(fn) |
fn(room, data) |
받기 콜백 추가. 아래 받기 |
addParser(fn) |
fn(args) |
!채널이름 인자 입력 처리 콜백 추가. 아래 명령 입력 처리 |
destroy() |
— | 채널을 목록에서 지워요. 등록한 콜백도 함께 버려져요 |
- 함수는 반환값이 없어요. 연결 전에 부르면 보내지지 않아요. 서버가 거절하면
error이벤트가 와요(권한 402, 값 오류 101, 한도 428). onReceived,addParser로 넣은 콜백은 하나씩 뺄 수 없어요.add가 같은 객체를 돌려주므로 다른 스크립트와 채널 이름이 겹치면 콜백이 섞여요. 고유한 이름을 쓰세요.
값 형식
보내는 값은 배열이고, 각 칸은 아래 형식만 그대로 전달돼요.
| 보낸 값 | 받는 값 |
|---|---|
| 문자열 | 문자열 |
| 0 이상의 정수 | 숫자 |
| 음수, 소수 | 숫자 |
true, false |
true, false |
undefined |
undefined(빈 칸) |
객체, 배열, null, 함수 |
빠져요. 뒤의 값이 한 칸씩 앞으로 당겨져요 |
구조가 있는 데이터는 칸을 나눠 보내거나 JSON.stringify로 문자열 한 칸에 넣으세요. 받은 문자열을 JSON.parse할 때는 try로 감싸세요.
ch.send(['move', 3, 5]); // 칸으로 나누기
ch.send(['state', JSON.stringify({ x: 3, y: 5 })]); // 문자열 한 칸
받기
onReceived 콜백은 (room, data)를 받아요.
| 키 | 설명 |
|---|---|
data.user |
보낸 사람 사용자 객체 |
data.type |
0(TO_ALL, send) 또는 1(ONLY_ME, sendTo·서버의 대상 전송·저장값) |
data.data |
값 배열 |
- 서버 발신: REST API로 보낸 데이터와 입장할 때 다시 받는 저장값은
data.user.auth가4이고 닉네임은 비어 있어요. 서버 발신인지는data.user.auth === 4로만 확인하세요. - 저장값도
auth4로 오므로,auth4라고 해서 REST API가 보낸 것이라고 단정할 수는 없어요. 저장값은 부관리자 이상만 쓸 수 있어요. - 그 밖의 데이터는 누구나 보낼 수 있어요. 닉네임만 보고 믿지 말고, 값의 형식과 범위를 검사하세요.
before.plugin에서false를 돌려주면onReceived콜백은 불리지 않아요(이벤트).
명령 입력 처리
기본 스킨에서 채팅창에 !채널이름 인자1 인자2를 입력하면 그 채널의 addParser 콜백이 (['인자1', '인자2'])로 불려요. 인자는 공백으로 나눈 문자열이에요. room.action.plugin('채널이름', ['인자1'])로 같은 처리를 코드에서 부를 수 있어요.
| 경우 | 결과 |
|---|---|
| 그 이름의 채널이 없음 | room.action.plugin()이 false. 기본 스킨은 입력을 일반 메시지로 보내요 |
before.plugin이 false를 돌려줌 |
false. 콜백을 부르지 않아요 |
어떤 콜백이 false를 돌려줌 |
false. 뒤 콜백은 불리지 않고, 기본 스킨은 입력을 일반 메시지로 보내요 |
| 그 밖 | true. 입력은 메시지로 보내지 않아요 |
parser는 내 브라우저에서만 돌아가요. 다른 사람에게 알리려면 콜백 안에서 send를 부르세요.
저장
save(values)는 채널의 마지막 상태를 서버에 남겨요. 나중에 들어온 사람은 입장할 때 저장값을 받아요(type 1, auth 4). 지금 접속한 사람에게는 보내지 않으므로 필요하면 send도 함께 부르세요.
| 항목 | 한도 |
|---|---|
| 쓸 수 있는 사람 | 부관리자 이상(아니면 오류 402) |
| 채널 하나의 저장값 | 무료 방 1KB, 유료 방 4KB |
| 채팅방 전체 저장값 | 60KB |
| 무료 방의 채널 수 | 사실상 하나. 다른 채널에 저장하면 기존 채널들의 저장값을 지워요 |
| 값 형식 | 문자열·숫자·불리언 |
- 채널 하나의 크기는 값 배열을 JSON으로 만들었을 때의 UTF-8 바이트 수예요. 전체 60KB는 채널 이름까지 포함한
{ 채널: 값 배열 }전체를 JSON으로 만든 크기예요. 넘거나 채널 이름이 규칙에 맞지 않으면 오류 101로 거절돼요. - 무료 방에서 저장값이 다른 채널 것으로 바뀌면 저장한 사람에게
control이벤트(type: 'pluginDataReplaced')가 와요. save로 저장한 값은 채팅 서버 메모리에만 있어요. 채팅방이 닫히거나 서버가 다시 시작되면 사라질 수 있고, 유료 방이 무료로 바뀌면 지워져요.- 내 서버에서 서버 REST API의
"save": true로 저장하면 유챗 서버에도 남아서, 채팅방이 닫히거나 서버가 다시 시작돼도 다음에 채팅방이 열릴 때 다시 읽혀요. 이때는 지금 접속한 사람에게도 함께 보내고, 한도는 위 표와 같아요. 오래 남아야 하는 값(방송 상태·점수·목표 금액 등)은 이 방법을 쓰세요.
전송 한도
| 한도 | 내용 |
|---|---|
| 무료 방 채널 전송 | 최근 60초 동안 데이터를 받은 사람 수의 합이 100을 넘을 수 없어요. 넘으면 오류 428 |
| 유료 방 | 채널 전송 한도 없음 |
| 패킷 수 | 같은 IP에서 1초에 보내는 패킷(메시지·명령·채널 전송 합계)이 10개에 이르면 오류 425, 더 넘으면 연결이 끊겨요 |
받은 사람 수는 이렇게 세어요.
| 전송 | 차감 |
|---|---|
send, REST API 전체 전송 |
그때 접속자 수 |
sendTo, REST API 대상 전송 |
1 |
- 차감한 값은 60초 뒤에 돌아와요. 예를 들어 접속자 20명인 무료 방에서는 1분에
send를 5번까지 보낼 수 있어요. - 페이지 스크립트의
send,sendTo와 REST API 전송이 같은 한도를 나눠 써요. - 한도에 걸린 무료 방에서는
save도 오류 428로 거절돼요.
자주 바뀌는 상태(위치, 타이머)는 매번 send하지 말고 묶어서 보내거나, 바뀔 때만 보내세요.
봐도 잘 이해가 되지 않나요? 문의 게시판에 질문을 남겨 주세요.