11 minute read

์›น ํ‘ธ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ• ์ผ ๋ชฉ๋ก์ด๋‚˜ ์ผ์ •์„ ์›๊ฒฉ์œผ๋กœ ์ธ์‡„ํ•  ์ˆ˜ ์žˆ๋‹ค.

(์˜ค๋Š˜์˜ ์šด์„ธ๋„ ๋ฝ‘์„ ์ˆ˜ ์žˆ๋‹ค)

์‹œ์ž‘์ 

์œ„ ๊ธ€์„ ๋ณด๊ณ  ์–ธ์  ๊ฐ€ ์˜์ˆ˜์ฆ ํ”„๋ฆฐํ„ฐ๋ฅผ ์‚ฌ์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

์™œ ๋งŒ๋“ค์—ˆ๋Š”๊ฐ€

์ตœ๊ทผ์— ์ฝ”๋”ฉํ•˜๋Š”๋ฐ ์ง‘์ค‘ํ•˜๋‹ค ๋ณด๋‹ˆ ์Šค๋งˆํŠธํฐ ์•Œ๋ฆผ์„ ๋†“์ณ์„œ ๋ฏธํŒ…์— ๋Šฆ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ฒผ๋Š”๋ฐ

๋ฌผ๋ฆฌ์ ์œผ๋กœ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉด ๋ฏธํŒ…์— ์•ˆ ๋Šฆ์„ ๊ฑฐ ๊ฐ™์•„์„œ ๋งŒ๋“ค์—ˆ๋‹ค.

๋ผ๊ณ  ์™œ ๋งŒ๋“ค์—ˆ๋ƒ๋Š” ์งˆ๋ฌธ์— ๋Œ€๋‹ตํ•˜๊ณ  ์žˆ์ง€๋งŒ

์‚ฌ์‹ค์€ ๊ทธ๋ƒฅ ๋งŒ๋“œ๋Š” ๊ฑฐ ์ž์ฒด๊ฐ€ ์ฆ๊ฑฐ์›Œ์„œ ๋งŒ๋“ค์—ˆ๋‹ค.

ํ”„๋ฆฐํ„ฐ ๊ตฌ๋งคํ•˜๊ธฐ

b300-image

๋น…์†”๋ก  B300 ์˜์ˆ˜์ฆํ”„๋ฆฐํ„ฐ

์–ด๋Œ‘ํ„ฐ ํฌํ•จ 63000์›์— ๊ตฌ๋งคํ–ˆ๋‹ค.

๋น…์†”๋ก  ํ”„๋ฆฐํ„ฐ๊ฐ€ ๊ตญ๋‚ด์—์„œ ํŒ๋งคํ•˜๋Š” ํ”„๋ฆฐํ„ฐ ์ค‘ ๋“œ๋ฌผ๊ฒŒ ๋งฅ์šฉ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์ง€์›ํ•œ๋‹ค.

ํ”„๋ฆฐํ„ฐ ๋“œ๋ผ์ด๋ฒ„ ์„ค์น˜

๋น…์†”๋ก  B300 ์†Œํ”„ํŠธ์›จ์–ด ๋‹ค์šด๋กœ๋“œ ์„ผํ„ฐ์—์„œ ์šด์˜์ฒด์ œ์— ๋งž๋Š” ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค.

๋งฅ์˜ ๊ฒฝ์šฐ

  1. ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜
  2. ์„ค์ • > ํ”„๋ฆฐํ„ฐ ๋ฐ ์Šค์บ๋„ˆ > ํ”„๋ฆฐํ„ฐ, ์Šค์บ๋„ˆ ๋˜๋Š” ํŒฉ์Šค ์ถ”๊ฐ€ ๋ฒ„ํŠผ
  3. Bixolon ํ”„๋ฆฐํ„ฐ ์„ ํƒ > ์‚ฌ์šฉ > ์†Œํ”„ํŠธ์›จ์–ด ์„ ํƒ > B300 ๊ฒ€์ƒ‰ ํ›„ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ ํƒํ•˜๋ฉด ๋œ๋‹ค.

์ด๋•Œ ์ด๋ฆ„์€ bix์ฒ˜๋Ÿผ ์งง๊ฒŒ ์ง“๋Š” ๊ฒŒ ๋‚˜์ค‘์— ํ„ฐ๋ฏธ๋„์ด๋‚˜ SDK์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•˜๋‹ค.

CLI์—์„œ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ๋ฒ•

๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๋‚˜๋ฉด ํ”„๋ฆฐํ„ฐ ์ƒํƒœ๋ฅผ lpstat ๋ช…๋ น์–ด๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

$ lpstat -p
bix ํ”„๋ฆฐํ„ฐ๊ฐ€ ๋Œ€๊ธฐ ์ค‘์ž…๋‹ˆ๋‹ค.  Fri Dec  5 01:58:04 2025 ์ดํ›„์— ํ™œ์„ฑํ™”๋จ

ํ…์ŠคํŠธ๋ฅผ euc-kr๋กœ ์ธ์ฝ”๋”ฉํ•˜๊ณ  ํ”„๋ฆฐํ„ฐ์— ์ž…๋ ฅํ•˜๋ฉด ์‹ค์ œ๋กœ ์ถœ๋ ฅ๋œ๋‹ค.

$ echo -e "์•ˆ๋…•ํ•˜์„ธ์š”\\n\\n\\n\\x1D\\x56\\x41" | iconv -f UTF-8 -t EUC-KR | lp -d bix

๋” ์œ ์šฉํ•ด์ง€๊ธฐ ์œ„ํ•ด์„ 

์Šค๋งˆํŠธํฐ, ์Šฌ๋ž™, ์›นํ›… ๋“ฑ๋“ฑ ๋งฅ๋ถ ์™ธ๋ถ€ ์–ด๋””์„œ๋“  ํ”„๋ฆฐํ„ฐ๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์Šฌ๋ž™ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ”„๋ฆฐํ„ฐ์— ๊ทธ๋Œ€๋กœ ์ถœ๋ ฅ๋˜๊ณ 

ํšŒ์˜๊ฐ€ ์‹œ์ž‘ํ•  ๋•Œ๊ฐ€ ๋˜๋ฉด ๊ตฌ๊ธ€ ์บ˜๋ฆฐ๋” ์ผ์ • ์ •๋ณด๋ฅผ ์ถœ๋ ฅ๋˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

WebPrint SDK

๋น…์†”๋ก  ํ”„๋ฆฐํ„ฐ๊ฐ€ ์ข‹์€ ๊ฒŒ ์œˆ๋„์šฐ, ๋งฅ, ์›น ๋“ฑ ๊ฐ์ข… ํ™˜๊ฒฝ์—์„œ ์“ธ ์ˆ˜ ์žˆ๋Š” SDK๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

SDK๋ฅผ ์„ค์น˜ํ•˜๊ณ  ํ”„๋ฆฐํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด localhost:18080 ์ฃผ์†Œ๋กœ ์„œ๋ฒ„๊ฐ€ ์‹คํ–‰๋˜๋Š”๋ฐ

ํ…์ŠคํŠธ, ๋ฐ”์ฝ”๋“œ ์ถœ๋ ฅ, ์ข…์ด ์ปคํŒ… ๋“ฑ๋“ฑ ๋ช…๋ น์–ด๋ฅผ API ์š”์ฒญ์œผ๋กœ ์ „์†กํ•˜๋ฉด ํ”„๋ฆฐํ„ฐ์— ์ „๋‹ฌ๋œ๋‹ค.

SDK ์„ค์ • & ํ…Œ์ŠคํŠธ

๋กœ๊ทธ์ธ ์‹œ ์ž๋™ ์‹คํ–‰ ON, https ๋Œ€์‹  http ์—ฐ๊ฒฐ์„ ์œ„ํ•ด SSL ์ธ์ฆ์„œ ์‚ฌ์šฉ์€ OFFํ–ˆ๋‹ค.

printer-sdk-preference

์•„๋ž˜ ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€์—์„œ ํ”„๋ฆฐํ„ฐ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๊ณ 

์ถœ๋ ฅ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์˜์ˆ˜์ฆ, ๋ฐ”์ฝ”๋“œ, ๊ทธ๋ฆผ ๋“ฑ๋“ฑ์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

https://bixolon.com/common/WebPrintSDK/Sample_PosPrinter.html

bixolon-sdk-test-page

SDK ๊ฐ„๋‹จ ์‚ฌ์šฉ๋ฒ•

ํ”„๋ฆฐํ„ฐ SDK ์„œ๋ฒ„์™€ ํ†ต์‹ ์„ ์‰ฝ๊ฒŒ ๋„์™€์ฃผ๋Š” JS ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค.

Software Web Print SDK Sample ์„ ๋‹ค์šด๋กœ๋“œํ•˜๋ฉด js ํด๋”์— ์œ„์น˜ํ•ด์žˆ๋‹ค.

jsfiles

์‚ฌ์šฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ๊ฐ„๋‹จํ•œ ํ…์ŠคํŠธ๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  ์˜์ˆ˜์ฆ ์ข…์ด๋ฅผ ์ž๋ฅธ๋‹ค.

var issueID = 1;

// ๊ฐ ์ธ์‡„ ์ž‘์—…๋งˆ๋‹ค ๊ณ ์œ  ID๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค.
setPosId(issueID);

// ํ”„๋ฆฐํ„ฐ ์ƒํƒœ๋ฅผ ํ™•์ธํ•œ๋‹ค. ํ”„๋ฆฐํ„ฐ๊ฐ€ ๊บผ์ ธ์žˆ์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค.
checkPrinterStatus();

// ํ…์ŠคํŠธ, ๋†’์ด, ๋„ˆ๋น„, ๋ณผ๋“œ ์—ฌ๋ถ€, ์–‘๊ฐ/์Œ๊ฐ, ๋ฐ‘์ค„, ํฐํŠธ ํƒ€์ž…, ์™ผ์ชฝ/์˜ค๋ฅธ์ชฝ/๊ฐ€์šด๋ฐ ์ •๋ ฌ์„ ์„ค์ •ํ•ด์„œ ์ถœ๋ ฅํ•œ๋‹ค.
printText("Hello World!\n", 0, 0, false, false, false, 0, 1);

// ์ข…์ด๊ฐ€ ์ž˜๋ฆฐ๋‹ค.
cutPaper(1);

// ํ์— ์Œ“์ธ ๋ช…๋ น์–ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ํ๋ฅผ ๋น„์šด๋‹ค.
var strSubmit = getPosData();

// ๋‹ค์Œ ์ธ์‡„ ์ž‘์—…์„ ์œ„ํ•ด ID๋ฅผ ๋ฐ”๊ฟ”์ค€๋‹ค.
issueID++;

// ํ”„๋ฆฐํ„ฐ๋กœ ๋ช…๋ น์„ ๋ณด๋‚ธ๋‹ค.
requestPrint("bix", strSubmit, function (result) {
  console.log("Print result:", result);
});

ํ•œ๊ธ€์ด ์•ˆ ๋‚˜์˜จ๋‹ค..? EUC-KR ์ธ์ฝ”๋”ฉํ•˜๊ธฐ

SDK์˜ printText() ํ•จ์ˆ˜๋กœ ์˜์–ด๋Š” ์ž˜ ์ถœ๋ ฅ๋˜๋Š”๋ฐ ํ•œ๊ธ€์€ ์ธ์ฝ”๋”ฉ์ด ๊นจ์ ธ์„œ ์™ธ๊ณ„ ๋ฌธ์ž๋กœ ๋‚˜์˜จ๋‹ค.

iconv-lite๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์œ ๋‹ˆ์ฝ”๋“œ๋ฅผ euc-kr(CP949) ํ˜•์‹์œผ๋กœ ์ธ์ฝ”๋”ฉ์„ ํ•ด์•ผ ํ•œ๋‹ค.

yarn์„ ์“ด๋‹ค๋ฉด buffer ํŒจํ‚ค์ง€๋„ ์ถ”๊ฐ€๋กœ ์„ค์น˜ํ•ด์•ผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋Ÿฐํƒ€์ž„ ์—๋Ÿฌ๊ฐ€ ์•ˆ ๋‚œ๋‹ค.

์ธ์ฝ”๋”ฉํ•œ hex ๋ฌธ์ž์—ด์„ SDK์˜ directPrintHex() ํ•จ์ˆ˜์— ๋„ฃ์–ด์ฃผ๋ฉด ํ•œ๊ธ€์ด ์ž˜ ์ถœ๋ ฅ๋œ๋‹ค.

import iconv from "iconv-lite";
import { Buffer } from "buffer";

function encodeToCP949String(text: string): string {
  const buffer = iconv.encode(text, "cp949");
  return Buffer.from(buffer).toString("hex");
}

function print(text) {
  //...

  const encodedText = encodeToCP949String(text);
  directPrintHex(encodedText);

  //...
}

์ปค์„œ ์—์ด์ „ํŠธ๋กœ ํ…์ŠคํŠธ ์ž…๋ ฅ์„ ๋ฐ›์•„ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ print()๋ฅผ ์ถœ๋ ฅํ•˜๋Š” UI๋ฅผ ๋งŒ๋“ค์–ด ๋‹ฌ๋ผ๊ณ  ํ•˜๋ฉด

๊ฐ„๋‹จํžˆ ์“ธ ์ˆ˜ ์žˆ๋Š” ํ”„๋ฆฐํ„ฐ GUI ์™„์„ฑ์ด๋‹ค.

printer-gui

์™ธ๋ถ€์—์„œ ์ด๋ฒคํŠธ ์ˆ˜์‹ ํ•˜๊ธฐ, ์›น ํ‘ธ์‹œ

์™ธ๋ถ€์—์„œ ๋งฅ ๋กœ์ปฌ์— ๋– ์žˆ๋Š” ํ”„๋ฆฐํ„ฐ SDK ์„œ๋ฒ„ ํ†ต์‹ ํ•  ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค.

๊ทธ๋ž˜์•ผ ์Šฌ๋ž™์ด๋‚˜ ๊ตฌ๊ธ€ ์บ˜๋ฆฐ๋” ์ด๋ฒคํŠธ์™€ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งฅ์˜ ๋กœ์ปฌ ํฌํŠธ๋ฅผ ๊ณต๊ฐœํ•˜๋Š” ๊ฑด ๋ณด์•ˆ์ƒ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ณ ,

๋ณ„๋„ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์Œ“์•„๋‘๊ณ  N์ดˆ๋งˆ๋‹ค ํด๋ง ํ•˜๋Š” ๊ฑด ๋น„ํšจ์œจ์ ์ด๋‹ค.

์˜ˆ์ „์— ์ˆ˜๊ฐ•์‹ ์ฒญ ์•Œ๋ฆผ ๋งŒ๋“ค ๋•Œ ์ผ๋˜ ์›น ํ‘ธ์‹œ๊ฐ€ ๋– ์˜ฌ๋ž๋‹ค.

์›น ํ‘ธ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์™ธ๋ถ€์—์„œ ๊ตฌ๊ธ€ ํ‘ธ์‹œ ์„œ๋ฒ„๋ฅผ ๊ฑฐ์ณ ๋งฅ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ง์ ‘ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์›น ํ‘ธ์‹œ ์‚ฌ์šฉ๋ฒ•

web-push npm ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฌ์›Œ์ง„๋‹ค.

์•ˆ์ „ํ•˜๊ฒŒ ํ‘ธ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•ด์„œ ์ „์†กํ•˜๊ธฐ ์œ„ํ•ด ๋žœ๋ค ๋ฌธ์ž์—ด์„ 5๊ฐœ๋‚˜ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š”๋ฐ

ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค ์ดํ•ดํ•  ํ•„์š”๋Š” ์—†๊ณ  ํ‚ค์— ๋งž๋Š” ๊ฐ’๋งŒ ์ž˜ ์ž…๋ ฅํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.

์›น ํ‘ธ์‹œ ํ”„๋กœํ† ์ฝœ ๊ธ€์— ๊ฐ ํ‚ค์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์ž˜ ๋‚˜์™€์žˆ๋‹ค.

1. VAPID ์ƒ์„ฑํ•˜๊ธฐ

VAPID(Voluntary Application Server Identification)๋Š” ์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ํ‘ธ์‹œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ผ ๋•Œ ์ž์‹ ์„ ์‹๋ณ„ํ•˜๋Š” ํ‘œ์ค€ ๊ทœ๊ฒฉ์ด๋ผ๊ณ  ํ•œ๋‹ค.

npm i -g web-push๋กœ web-push ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๊ณ 

์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ณต๊ฐœํ‚ค, ๋น„๋ฐ€ํ‚ค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.

> web-push generate-vapid-keys --json
> {"publicKey":"AAAAAAAAAA","privateKey":"BBBBBBBBBB"}

2. ํ‘ธ์‹œ ๊ตฌ๋…ํ•˜๊ธฐ

๋ธŒ๋ผ์šฐ์ €์—์„œ ์•Œ๋ฆผ ๊ถŒํ•œ์„ ์–ป๊ณ  ์„œ๋น„์Šค ์›Œ์ปค๋ฅผ ๋“ฑ๋กํ•ด์„œ ์•Œ๋ฆผ์„ ๊ตฌ๋…ํ•œ๋‹ค.

์ด๋•Œ applicationServerKey์— ์œ„์—์„œ ์ƒ์„ฑํ•œ ๊ณต๊ฐœํ‚ค๋ฅผ ๋„ฃ์–ด์ค€๋‹ค.

// 1. ๋ธŒ๋ผ์šฐ์ € ์•Œ๋ฆผ ๊ถŒํ•œ ์–ป๊ธฐ
await Notification.requestPermission();

// ์„œ๋น„์Šค ์›Œ์ปค ๋“ฑ๋กํ•˜๊ธฐ
const registration = await navigator.serviceWorker.register("/sw.js");

// ์›น ํ‘ธ์‹œ ๊ตฌ๋…ํ•˜๊ธฐ
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: "AAAAAAAAAA",
});

console.log(subscription.toJSON());

๊ตฌ๋… ์ •๋ณด๋Š” ๊ฐ’์„ 3๊ฐœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

{
  "endpoint": "https://fcm.googleapis.com/fcm/send/CCCCCCCCCC",
  "expirationTime": null,
  "keys": {
    "p256dh": "DDDDDDDDDD",
    "auth": "EEEEEEEEEE"
  }
}

3. ํ‘ธ์‹œ ๋ณด๋‚ด๊ธฐ

ํ„ฐ๋ฏธ๋„์—์„œ ์ƒ์„ฑํ•œ VAPID ํ‚ค์™€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐ˜ํ™˜ํ•œ ๊ตฌ๋… ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด

์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ‘ธ์‹œ๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

web-push send-notification  \
  --vapid-subject=mailto:example@test.com \
  --vapid-pubkey=AAAAAAAAAA \
  --vapid-pvtkey=BBBBBBBBBB \
  --endpoint=https://fcm.googleapis.com/fcm/send/CCCCCCCCCC \
  --key=DDDDDDDDDD \
  --auth=EEEEEEEEEE \
  --payload=์•ˆ๋…•ํ•˜์„ธ์š”

ํ˜น์€ ๋…ธ๋“œ ์„œ๋ฒ„์—์„œ ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

import webpush from "web-push";

webpush.setVapidDetails(
  "mailto:example@test.com",
  "AAAAAAAAAA", // VAPID PUBLIC KEY
  "BBBBBBBBBB" // VAPID PRIVATE KEY
);

const subscription = {
  endpoint: "https://fcm.googleapis.com/fcm/send/CCCCCCCCCC",
  keys: {
    p256dh: "DDDDDDDDDD",
    auth: "EEEEEEEEEE",
  },
};

webpush.sendNotification(subscription, message);

4. ํ‘ธ์‹œ ๋ฐ›๊ธฐ

์„œ๋น„์Šค ์›Œ์ปค(sw.js)์— ํ‘ธ์‹œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•ด๋†“์œผ๋ฉด ์›น ํ‘ธ์‹œ๋กœ ๋ณด๋‚ธ ์ •๋ณด๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

self.addEventListener("push", (event) => {
  const text = event.data.text();

  console.log("ํ‘ธ์‹œ๋กœ ๋ฐ›์€ ํ…์ŠคํŠธ: ", text);
});

ํ‘ธ์‹œ๋ฅผ ๋ฐ›์œผ๋ฉด ํ”„๋ฆฐํ„ฐ SDK ์„œ๋ฒ„๋กœ ์ธ์‡„ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

์„œ๋น„์Šค ์›Œ์ปค์˜ ์ข‹์€ ์ 

์›น ํŽ˜์ด์ง€๊ฐ€ ๋‹ซํ˜€์žˆ์–ด๋„, ์‹ฌ์ง€์–ด ๋งฅ๋ถ์ด ์ž ๊ธˆ ์ƒํƒœ์ผ ๋•Œ๋„

WIFI๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  ํฌ๋กฌ์ด ์™„์ „ํžˆ ๊บผ์ง„ ์ƒํƒœ๋งŒ ์•„๋‹ˆ๋ผ๋ฉด ํ‘ธ์‹œ๋ฅผ ๋ฐ›์•„์„œ ๋ช…๋ น์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์„œ๋น„์Šค ์›Œ์ปค์—์„œ SDK ์„œ๋ฒ„๋กœ ์ธ์‡„ ์š”์ฒญ ๋ณด๋‚ด๊ธฐ

๋Œ€์‹  ์„œ๋น„์Šค ์›Œ์ปค๋ฅผ ์‚ฌ์šฉํ•  ๋• ์ œ์•ฝ์ด ์žˆ๋‹ค.

๋ฌธ์ œ 1: JS SDK๊ฐ€ ์„œ๋น„์Šค ์›Œ์ปค์—์„œ ์ง€์›ํ•˜์ง€ ์•Š๋Š” XMLHttpRequest๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

โ†’ ์ปค์„œ ์—์ด์ „ํŠธ์—๊ฒŒ fetch๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์žฌ์ž‘์„ฑํ•ด๋‹ฌ๋ผ๊ณ  ํ•œ๋‹ค.

๋ฌธ์ œ 2: ํ•œ๊ธ€ ์ธ์ฝ”๋”ฉ์„ ์œ„ํ•œ iconv-lite ํŒจํ‚ค์ง€๋ฅผ ์“ฐ๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค. ๊ฐ„๋‹จํžˆ euc-kr ์ธ์ฝ”๋”ฉ์„ ํ•ด์ฃผ๋Š” ํŒจํ‚ค์ง€๊ฐ€ ๊ฒ€์ƒ‰ํ•ด๋„ ์•ˆ ๋‚˜์˜จ๋‹ค.

โ†’ ์ปค์„œ ์—์ด์ „ํŠธ์—๊ฒŒ euc-kr ์ธ์ฝ”๋”ฉ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•ด๋‹ฌ๋ผ๊ณ  ํ•˜๊ณ , vitest๋ฅผ ์„ค์น˜ํ•ด ์ฃผ๊ณ  ํ…Œ์ŠคํŠธํ•ด๊ฐ€๋ฉด์„œ ํ‹€๋ฆฐ ๋ถ€๋ถ„์„ ์Šค์Šค๋กœ ํŒŒ์•…ํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋„๋ก ํ•œ๋‹ค.

ํ‘ธ์‹œ ๊ตฌ๋… ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•œ ์„œ๋ฒ„ ์ž‘์—…

ํ‘ธ์‹œ ๊ตฌ๋… ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€๋” ๋งŒ๋ฃŒ๋  ๋•Œ๊ฐ€ ์žˆ๋‹ค.

๊ทธ๋•Œ๋งˆ๋‹ค ๊ตฌ๋… ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ˜์†”์— ์ถœ๋ ฅํ•ด์„œ ๋‹ค์‹œ ์„œ๋ฒ„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ๋„ฃ์–ด์ฃผ๊ธฐ ๊ท€์ฐฎ์œผ๋ฏ€๋กœ

์–ด๋”˜๊ฐ€์— ์ €์žฅํ•ด์„œ ๊ฐ€์ ธ๋‹ค ์จ์•ผ ํ•œ๋‹ค.

k8s PV์™€ sqlite๋ฅผ ์“ฐ๊ฑฐ๋‚˜, ๋ณ„๋„ DB ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ

์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋„ ๊ฐ„๋‹จํ•˜๋ฏ€๋กœ ๊นƒํ—™ ๋น„๊ณต๊ฐœ ๋ ˆํฌ๋ฅผ ํŒŒ์„œ JSON ํŒŒ์ผ์„ ํ†ต์งธ๋กœ ์ €์žฅํ–ˆ๋‹ค.

github-repo-storage

์ „์ฒด ๊ตฌ์กฐ

์ธ์‡„ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ํ‘ธ์‹œ๋ฅผ ๋ณด๋‚ด๋Š” API๋“ค์„ ๋งŒ๋“ค๋ฉด ๋์ด๋‹ค.

์ „์ฒด ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

diagram

zapier, ์Šฌ๋ž™์—์„œ ์›นํ›…์„ ํ†ตํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด

๋…ธ๋“œ ์„œ๋ฒ„๊ฐ€ ๊ตฌ๊ธ€ ํ‘ธ์‹œ ์„œ๋ฒ„์— ์ „๋‹ฌํ•ด ์ฃผ๊ณ 

ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ € ๋ฐฑ๊ทธ๋ผ์šด๋“œ์— ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š” ์„œ๋น„์Šค ์›Œ์ปค๊ฐ€ ํ”„๋ฆฐํ„ฐ SDK์— ์ธ์‡„ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

์‚ฌ์šฉ ์‚ฌ๋ก€

๋ฏธํŒ… 2๋ถ„ ์ „์— ํ”„๋ฆฐํŠธ ์ถœ๋ ฅํ•˜๊ธฐ

zapier์— ๊ตฌ๊ธ€ ์บ˜๋ฆฐ๋”๋ฅผ ์—ฐ๋™ํ•ด์„œ ํšŒ์˜ 2๋ถ„ ์ „์— ์›นํ›…์„ ์ „์†กํ•˜๋„๋ก ์„ค์ •ํ•œ๋‹ค.

zapier-setup

๋•๋ถ„์— ํšŒ์˜ ์ž˜ ์•ˆ ๋Šฆ๋Š”๋‹ค.

๋ ˆ์ด์บ์ŠคํŠธ๋กœ ๋ฐ”๋กœ ์ถœ๋ ฅํ•˜๊ธฐ

๋ ˆ์ด์บ์ŠคํŠธ์—์„œ ๋ฐ”๋กœ ๋ฉ”๋ชจ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์˜ค๋Š˜์˜ ์šด์„ธ

๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์˜ค๋Š˜์˜ ์šด์„ธ๊ฐ€ ๋‚˜์˜ค๊ฒŒ ํ–ˆ๋‹ค.

ํšŒ์‚ฌ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ํ”„๋ฆฐํ„ฐ ์ถœ๋ ฅ ๊ถŒํ•œ์„ ์—ด์–ด๋ดค๋‹ค

์Šฌ๋ž™์— print_yj ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ํ”„๋ฆฐํ„ฐ์—์„œ ํ…์ŠคํŠธ๊ฐ€ ์ธ์‡„๋˜๋„๋ก ํ–ˆ๋‹ค.

๊ทธ๋žฌ๋”๋‹ˆ

person-crazy-1

์ด์ƒํ•œ ์‚ฌ๋žŒ๋„ ์žˆ๊ณ  (์ฐจ๋‹จํ–ˆ๋‹ค)

person-ordinary

๋ณดํ†ต์€ ์ด๋Ÿฐ ๊ฑฐ ๋ณด๋‚ธ๋‹ค.

person-review

์ฝ”๋“œ๋ฆฌ๋ทฐ ์š”์ฒญ๋„ ๋ณด๋‚ธ๋‹ค.

person-ceo

์‚ฌ์žฅ๋‹˜๋„ ์ผ ์—ด์‹ฌํžˆ ํ•˜๋ผ๊ณ  ๊ฒฉ๋ ค์˜ ๋ง์”€์„ ๋ณด๋‚ด์…จ๋‹ค

person-poet

์ด๋ฆ„์œผ๋กœ ์‚ผํ–‰์‹œ ๋ณด๋‚ด๋Š” ์‚ฌ๋žŒ๋„ ์žˆ๋‹ค

person-crazy-2

์ด์ƒํ•œ ์‚ฌ๋žŒ ์ฐจ๋‹จํ•œ ๊ฑฐ ๊ฑธ๋ ธ๋‹ค. ๋‹ค์‹œ ํ’€์–ด์คฌ๋‹ค.

๋งˆ๋ฌด๋ฆฌ

  • AI ์—์ด์ „ํŠธ ๋•๋ถ„์— ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๊ฐ€ ์ ์  ๋Š˜์–ด๋‚œ๋‹ค. AI๋ž‘ ์‹ธ์šฐ์ง€ ๋ง๊ณ  ์—ด์‹ฌํžˆ ์ด๊ฒƒ์ €๊ฒƒ ๋งŒ๋“ค์–ด๋ด์•ผ๊ฒ ๋‹ค.
  • ์ด๋Ÿฐ ๊ฑธ ๋ญ ํ•˜๋Ÿฌ ๋งŒ๋“ค์—ˆ๋ƒ๋ฉฐ ์•ฝ๊ฐ„ ์–ด์ด์—†์ด ํ•˜๋Š” ์‚ฌ๋žŒ์„ ๋ณด๋Š” ๊ฒŒ ์ฆ๊ฒ๋‹ค.

game-meme