Skip to content
This repository has been archived by the owner on Feb 19, 2023. It is now read-only.
/ streamingChat Public archive

๐Ÿค” An imaginary streaming chat service built with Go, Redis and gRPC

Notifications You must be signed in to change notification settings

umi0410/streamingChat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

9 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Streaming Chat service using GRPC

์ƒ์ƒ ์†์˜ ์ŠคํŠธ๋ฆฌ๋ฐ ์ฑ„ํŒ… ์„œ๋น„์Šค

(์œ ํŠœ๋ธŒ ๋ผ์ด๋ธŒ ์ฑ„ํŒ… ๊ฐ™์€ ๊ฑธ ์ƒ์ƒ ์ค‘...)

์‹ค์ œ ์ฑ„ํŒ… ์„œ๋น„์Šค๋กœ ์šด์˜ํ•˜๊ธฐ ์œ„ํ•จ์ด ์•„๋‹Œ ์ด๋Ÿฐ ์ €๋Ÿฐ ๊ฐœ๋ฐœ์  ๋‚ด์šฉ๋“ค์„ ์‹ค์ œ๋กœ ์ ์šฉ์‹œ์ผœ๋ณด๊ฑฐ๋‚˜ ์ƒ์ƒํ•ด๋ณด๊ธฐ ์œ„ํ•œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

  • gRPC๋ฅผ ํ†ตํ•œ ์„œ๋ฒ„ <---> ํด๋ผ์ด์–ธํŠธ ๊ฐ„์˜ ์–‘๋ฐฉํ–ฅ ํ†ต์‹ 
  • Go ์–ธ์–ด ํŠน์œ ์˜ ๊ฐ•๋ ฅํ•œ ๋™์‹œ์„ฑ ์ง€์›์„ ํ™œ์šฉ
  • Redis stream ๋ฐ Redis Pub/Sub์„ ๋ฐ”ํƒ•์œผ๋กœ ํ•œ ์„œ๋ฒ„๊ฐ„์˜ ํ†ต์‹ 
  • ๋ณต์žกํ•œ Join์ด ํ•„์š” ์—†๊ณ  ๋‹ค๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌ์–ผํƒ€์ž„์œผ๋กœ ์ €์žฅํ•ด์•ผํ•˜๋ฏ€๋กœ No SQL DB ์ด์šฉ
  • ์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ ๋ฐ ๊ฐ์ข… Create, Read ๊ธฐ๋Šฅ์€ Java Spring์˜ MVC์™€ JPA๋กœ ํŠผํŠผํ•˜๊ณ  ์‰ฝ๊ฒŒ ๊ฐœ๋ฐœ
  • ํŠธ๋ž˜ํ”ฝ์ด ๋ชฐ๋ฆด ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด ์ฑ„ํŒ… ์ด๋ฒคํŠธ๋Š” Redis stream๋ฅผ ๋ฒ„ํผ๋กœ ๋‘๊ณ  ์›Œ์ปค๊ฐ€ ์˜์†ํ™”
  • k8s + minikube๋ฅผ ์ด์šฉํ•ด ๋กœ์ปฌ์—์„œ๋„ ์†์‰ฝ๊ฒŒ ์ „์ฒด ์ธํ”„๋ผ๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๋„๋ก ํ•จ.

๐Ÿง๐Ÿค” ๋จธ๋ฆฟ ์† ์ƒ์ƒ๋“ค โ“โ‰๏ธ

  • gRPC๋Š” ์–ด๋–ค ๊ฑธ๊นŒ..? RESTful API๋‚˜ GrpahQL์ด๋ž‘ ๋น„๊ตํ–ˆ์„ ๋•Œ๋Š” ์–ด๋–จ๊นŒ? ์›น์†Œ์ผ“๊ณผ ๋น„๊ตํ–ˆ์„ ๋• ์–ด๋–จ๊นŒ?
  • ๋ฉ”์‹œ์ง€ ํ(Redis stream)์„ ์ด์šฉํ•ด์„œ ์‹ค์ œ๋กœ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ๊ฐ„์˜ ํ†ต์‹ ์„ ํ•ด๋ณด๊ณ ์‹ถ๋‹ค.
    • ๋ฉ”์‹œ์ง€ ํ๋ฅผ ์“ฐ๊ณ ๋Š” ์‹ถ์€๋ฐ Kafka๋‚˜ RabbitMQ๋Š” ๋ฉ”์‹œ์ง€ ํ๋ฅผ ์ด์šฉํ•œ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ณ๋ฅผ ๊ฒฝํ—˜ํ•ด๋ณธ๋‹ค๊ธฐ๋ณด๋‹จ ํŠน์ • ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์ง€์‹์ด ๋งŽ์ด ํ•„์š”ํ•œ ๋Š๋‚Œ์ด๊ณ , ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ์‰ฝ์ง€ ์•Š๋‹ค.
    • ๊ด€๋ฆฌํ˜•์ธ SNS + SQS ์กฐํ•ฉ์„ ์จ๋ณด๊ธด ํ–ˆ์ง€๋งŒ ๊ตฌ์„ฑ ์ž์ฒด๊ฐ€ ํ•œ ๋ˆˆ์— ์•ˆ๋ณด์ด๋Š” ๋ถˆํŽธ์ด ์žˆ์—ˆ๋‹ค.
    • ์‹ค์ œ ์šด์˜ํ•  ์„œ๋น„์Šค๋Š” ์•„๋‹ˆ๊ธฐ๋„ ํ•˜๊ณ  Redis๋Š” ์บ์‹ฑ์—๋„ ํ•„์ˆ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ์ˆ ์ด๋ผ ๊ด€์‹ฌ์žˆ์—ˆ๊ธฐ์— ์ปจํ…Œ์ด๋„ˆ๋กœ ๊ฐ€๋ณ๊ฒŒ ์ด์šฉํ•˜๋ฉด ๋  ๋“ฏ~!
  • ์–ผ๋งˆ๋‚˜ ํŠธ๋ž˜ํ”ฝ์ด ๋ชฐ๋ฆฌ๋ฉด DB๊ฐ€ ์žฅ์• ๊ฐ€ ๋‚ ๊นŒ? ์ง„์งœ ๋ฒ„ํผ๊ฐ€ ํ•„์š”ํ• ๊นŒ?
  • Golang์ด ์ง„์งœ ๋™์‹œ์„ฑ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์žˆ์–ด ์„ฑ๋Šฅ์ด ์ข‹์„๊นŒ? ์–ผ๋งˆ๋‚˜ ์ข‹์„๊นŒ?
  • ์–‘๋ฐฉํ–ฅ ํ†ต์‹ ์„ ํ•˜๋Š” ๊ฒฝ์šฐ ์‹ค์ œ ์šด์˜ํ•  ๋•Œ์—๋Š” ์–ด๋–ป๊ฒŒ Gracefully shutdown์„ ํ•  ์ˆ˜ ์žˆ์„๊นŒ? Golang์—์„œ๋Š” Context๋ฅผ ํ†ตํ•ด ์ตœ๋Œ€ํ•œ Gracefulํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ..
  • ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ๋Š” ์–ด๋–ป๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

gRPC & Protobuf

์ปดํŒŒ์ผํ•˜๋Š” ๋ฐฉ๋ฒ•

$ protoc --go_out=. --go_opt=paths=source_relative \
    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
    pb/chat.proto

gRPC์˜ Stream์„ ์ด์šฉํ•œ ์ฑ„ํŒ… ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆฌ๋ฐ

Redis

Redis Pub/Sub์„ ์ด์šฉํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก

  • ๊ฐ ์„œ๋ฒ„๋Š” ์ž์‹ ๊ณผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ํด๋ผ์ด์–ธํŠธ ์ •๋ณด๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒ ์ž์‹ (์„œ๋ฒ„)์ด ์ƒˆ๋กœ์šด ๋ฉ”์‹œ์ง€ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.
  • ์–ด๋–ค ์ฑ„ํŒ… ์„œ๋ฒ„ replica์—์„œ ์ฑ„ํŒ… ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋˜ ๋‹ค๋ฅธ ์ฑ„ํŒ… ์„œ๋ฒ„ replica๋Š” ๊ทธ ์ด๋ฒคํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ์•Œ๊ณ  ์ž์‹ ๊ณผ ์—ฐ๊ฒฐ๋œ ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒŒ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์„๊นŒ?
  • ์ด๋•Œ Redis Pub/Sub์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๋‹ค!
  • Redis stream์„ ์“ฐ๋Š” ๊ฑด ์–ด๋–จ๊นŒ?
    • Consumer group ๊ด€๋ฆฌ๋‚˜ ACKnowledge ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” Redis stream๋ณด๋‹ค๋Š” Pub/Sub์ด Real-time ์„ฑ๊ฒฉ์˜ ์ด ์ŠคํŠธ๋ฆฌ๋ฐํ˜• ์ฑ„ํŒ…์— ๋” ์–ด์šธ๋ฆด ๊ฒƒ ๊ฐ™์Œ.
    • ๋งŒ์•ฝ Pub/Sub์„ ์ด์šฉํ–ˆ๋‹ค๊ฐ€ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์–ด์„œ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด์ค„ ์ˆ˜ ์—†๋‹ค๋ฉด?
      • ์ผ๋‹จ์€ ํด๋ผ์ด์–ธํŠธ๋Š” ์ž์‹ ๊ณผ ์—ฐ๊ฒฐ๋œ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์œผ๋ฉด ์žฌ๋นจ๋ฆฌ ๋‹ค๋ฅธ ์„œ๋ฒ„์™€ ์ปค๋„ฅ์…˜์„ ๋งบ๋„๋ก ๋˜์–ด์žˆ์Œ.
      • ๊ทธ ์‚ฌ์ด์— ๋ฐœ์ƒํ•œ ์ฑ„ํŒ…์€? - ์‚ฌ์‹ค ๊ทธ๋ƒฅ ๋ฌด์‹œํ•œ๋‹ค. ์ด๋Ÿฐ ๊ฒƒ๊นŒ์ง€ ๋‹ค ์‹ ๊ฒฝ์„ ์“ฐ๋Š” ๊ฑด ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์„ ์ ์šฉํ•œ ์•„ํ‚คํ…์ณ๋ฅผ ์ƒ์ƒํ•ด๋ณด๊ณ  ์ ์šฉ์‹œ์ผœ๋ณด๋Š” ์ด ํ”„๋กœ์ ํŠธ์™€๋Š” ์ ์  ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€์–ด์ง€๊ณ  ์ฑ„ํŒ… ๋„๋ฉ”์ธ์„ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๋„๋ฉ”์ธ ๋กœ์ง์ด๋‚˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ ์  ์ง‘์ค‘ํ•˜๊ฒŒ ๋  ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ. ์ตœ๋Œ€ํ•œ ๋ฆฌ์–ผํƒ€์ž„ ์ŠคํŠธ๋ฆฌ๋ฐํ˜•์ด๋ผ๋Š” ๊ฒƒ์— ์ดˆ์ ์„ ๋‘”๋‹ค!

Redis stream์„ ์ด์šฉํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก

  • Real-time ์„ฑ๊ฒฉ์ด ์•„๋‹Œ ๋‹จ์ˆœํžˆ ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ๋ฅผ DB์— ์˜์†ํ™” ์‹œํ‚ค๋Š” ๊ฒฝ์šฐ์—๋Š” ์žฌ๋นจ๋ฆฌ ์ฑ„ํŒ… ์ด๋ฒคํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ๋“ค์—๊ฒŒ ๋ฟŒ๋ ค์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ํ•ด๋‹น ์ด๋ฒคํŠธ๊ฐ€ ์ž˜ ์ฒ˜๋ฆฌ๋๋Š”์ง€ ACKnowledgeํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ. ๋”ฐ๋ผ์„œ Pub/Sub ๋ณด๋‹ค๋Š” Redis์˜ Stream์„ ์ด์šฉํ•ด Kafka์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
  • Pub/Sub์˜ ๊ฒฝ์šฐ Consumer Group์ด๋ผ๋Š” ๊ฐœ๋…์ด ํ•„์š” ์—†์ด ๊ฐ ๋ฐฑ์—”๋“œ replica๋“ค์ด ๋™์ผํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋ชจ๋‘ ์ „๋‹ฌ๋ฐ›์•„์•ผํ–ˆ์ง€๋งŒ ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ๋ฅผ DB์— ์˜์†ํ™” ์‹œํ‚ค๋Š” ์ž‘์—…์€ Consumer group์˜ ๊ฐœ๋…์„ ์ด์šฉํ•ด group ๋‚ด์˜ replica ์ค‘ ํ•œ ๋ช…๋งŒ ์ด๋ฒคํŠธ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๋”ฐ๋ผ์„œ Consumer group์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด Pub/Sub์ด ์•„๋‹Œ Redis stream์„ ์ด์šฉํ•œ๋‹ค.

Redis์˜ TTL์„ ์ด์šฉํ•œ ์‹ค์‹œ๊ฐ„ ์ธ๊ธฐ ๋‹จ์–ด

์‚ฌ์‹ค ๋ณ„๋กœ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์€ ์•„๋‹Œ๋ฐ ใ…Žใ…Ž.. ๋‹ค์–‘ํ•œ Redis์˜ ์œ ์ฆˆ์ผ€์ด์Šค๊ฐ€ ๊ถ๊ธˆํ•ด์„œ ์ƒ์ƒํ•ด๋ดค๋‹ค. ๊ทผ๋ฐ ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ์…‹์„ ๋ฐ”ํƒ•์œผ๋กœ ํ˜•ํƒœ์†Œ ๋ถ„์„์„ ํ•ด์„œ ์ธ๊ธฐ ๋‹จ์–ด๋ฅผ ์นด์šดํŠธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ๊ทธ๋ƒฅ ๊ณต๋ฐฑ์œผ๋กœ Split ์‹œ์ผœ์„œ ๋‹จ์–ด๋กœ ์นด์šดํŠธ ํ•˜๋‹ค๋ณด๋‹ˆ ๊ทธ๋ƒฅ ๋™์‚ฌ๋“ค์ด ์ธ๊ธฐ ๋‹จ์–ด๋กœ ์„ ์ •๋˜๊ธดํ–ˆ๋‹ค.

๋ณดํ†ต Realtime leaderboard๋ผ๋Š” ์ปจ์…‰์œผ๋กœ Sorted Set์„ ์ด์šฉํ•ด ๋ฆฌ์–ผํƒ€์ž„ ๋žญํ‚น ์„œ๋น„์Šค๋ฅผ ์†Œ๊ฐœํ•˜๋Š” ๊ฒƒ ๊ฐ™์€๋ฐ ์ด ๊ฒฝ์šฐ๋Š” ์ „์ฒด ๊ธฐ๊ฐ„ ๋™์•ˆ์— ๋Œ€ํ•œ Ranking๋งŒ ์ œ๊ณตํ•˜๊ณ  ํŠน์ • ๊ธฐ๊ฐ„ ๋™์•ˆ์˜ ๋žญํ‚น์€ ์ œ๊ณตํ•  ์ˆ˜ ์—†๋‹ค. Sorted Set์— TTL์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๊ธฐ๋„ ํ•˜๊ณ , ๊ฒฐ๊ตญ ํŠน์ • ๊ธฐ๊ฐ„ ๋™์•ˆ์˜ ์ด๋ฒคํŠธ๋กœ๋งŒ ๋žญํ‚น์„ ์ •๋ ฌํ•˜๋ ค๋ฉด ์ด์šฉ๋˜๋Š” ๊ฐ ์ด๋ฒคํŠธ์˜ ์ •๋ณด๊ฐ€ ์žˆ์–ด์•ผํ•œ๋‹ค. ๊ทผ๋ฐ ๋งˆ์นจ ์ด์— ๋Œ€ํ•ด ๋‚˜์˜ ์ƒ์ƒ๊ณผ ๋น„์Šทํ•œ ํ•ด๊ฒฐ์ฑ…์„ ๋‹ค๋ฃฌ ์Šคํƒ์˜ค๋ฒ„ ํ”Œ๋กœ์šฐ ๊ธ€์ด ์žˆ์—ˆ๋‹ค.

  • Redis์˜ Expiration time(TTL)์„ ์ด์šฉํ•˜๋ฉด ์ธ๊ธฐ ๋‹จ์–ด ์ง‘๊ณ„์— ์‚ฌ์šฉ๋˜๋Š” ๋‹จ์–ด ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‰ฝ๊ฒŒ ์•Œ์•„์„œ ํŠน์ • ์‹œ๊ฐ„ ์ดํ›„ ์‚ญ์ œ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋Ÿผ ํŠน์ • ๊ธฐ๊ฐ„(์˜ˆ๋ฅผ ๋“ค์–ด ์ง€๋‚œ 1๋ถ„) ๊ฐ„์˜ ์ธ๊ธฐ ๋‹จ์–ด๋ฅผ ๋ณด๊ธฐ ์œ„ํ•ด์„  TTL์„ 1๋ถ„์œผ๋กœ ์„ค์ •ํ•ด๋‘๊ณ  ๋‚จ์•„์žˆ๋Š” ๋‹จ์–ด ์ด๋ฒคํŠธ๋งŒ์œผ๋กœ ์ง‘๊ณ„ํ•˜๋ฉด ๋œ๋‹ค.
  • ๋‹จ์ ์€ Sorted Set์„ ์ด์šฉํ•  ๋•Œ๋Š” ๋žญํ‚น ์ˆœ์œ„ ์ž์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ ์ €์žฅ๋œ๋‹ค๋Š” ๊ฒƒ์ด์—ˆ๋Š”๋ฐ, ์ด ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•˜๋ฉด ์ •๋ ฌ์€ ๋งค ์ฟผ๋ฆฌ ๋•Œ๋งˆ๋‹ค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋‹ด๋‹นํ•ด์•ผํ•œ๋‹ค.
  • hotWord@{{word}}@{{username}}: 0 ์ด๋Ÿฐ ์‹์œผ๋กœ Key๋ฅผ ์„ค์ •ํ•˜๊ณ  empty value๋ฅผ ๋‹ด์€ ๋’ค hotWord@{{word}}@*์— ํ•ด๋‹นํ•˜๋Š” key์˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ์–ด ์ •๋ ฌํ•˜๋ฉด ๋œ๋‹ค.
  • "Keeping Redis simple" ์ด๋ผ๋Š” ์ฒ ํ•™ ๋•Œ๋ฌธ์ธ์ง€ ๋‹ค์†Œ @ ๋กœ 'howWord ๋žญํ‚น ์‚ฐ์ถœ์— ์‚ฌ์šฉ๋˜๋Š” ํ‚ค์ด๋ฉฐ {{word}}๋ผ๋Š” ๋‹จ์–ด์— ๋Œ€ํ•œ {{username}} ์œ ์ €์˜ ์ฑ„ํŒ… ๊ธฐ๋ก์ด๋‹ค' ๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ด ๋‹ค์†Œ ๊น”๋”ํ•˜์ง„ ์•Š์•„๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋ญ RDB๋‚˜ ๋‹ค๋ฅธ DB๋ฅผ ์ผ์œผ๋ฉด TTL์„ ์œ„ํ•ด ๋˜ ๋‹ค๋ฅธ ์ด๋Ÿฐ ์ €๋Ÿฐ ๊ณ ์ƒ์„ ํ–ˆ์–ด์•ผํ•  ๊ฒƒ ๊ฐ™๊ธด ํ•˜๋‹ˆ๊นŒ Redis๋ฅผ ์šฉ์„œํ•ด์ฃผ๋Š” ๊ฑธ๋กœ ํ•˜๊ฒ ๋‹ค.

์ฐธ๊ณ  ์ž๋ฃŒ

์ƒ˜ํ”Œ ์ฑ„ํŒ… ๋ฐ์ดํ„ฐ - https://github.com/songys/Chatbot_data

About

๐Ÿค” An imaginary streaming chat service built with Go, Redis and gRPC

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published