์๋น์ค๋ช : Baseball Live Chat (๊ฐ์นญ) ํต์ฌ ๊ฐ์น: ์ผ๊ตฌ ๊ฒฝ๊ธฐ๋ฅผ ๋ณด๋ฉฐ ์ค์๊ฐ์ผ๋ก ์ํตํ ์ ์๋ ์ปค๋ฎค๋ํฐ ํ๋ซํผ
- ์ค๋์ ์ผ๊ตฌ ๊ฒฝ๊ธฐ 5๊ฐ ๋ฆฌ์คํธ ํ์
- ๊ฐ ๊ฒฝ๊ธฐ๋ณ ํ์ฌ ์ฑํ ์ฐธ์ฌ์ ์, ์ต๊ทผ ์ฑํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
- ๊ฒฝ๊ธฐ ์ํ (๊ฒฝ๊ธฐ ์ /์งํ ์ค/์ข ๋ฃ) ํ์
- ๊ฒฝ๊ธฐ ๊ธฐ๋ณธ ์ ๋ณด (ํ๋ช , ์๊ฐ, ์ค์ฝ์ด)
- ์ผ๊ตฌ ์ค๊ณ ์์ ์์ญ (iframe ๋๋ ์ธ๋ถ ๋งํฌ)
- ์ค์๊ฐ ์ฑํ ์์ญ
- ์ฌ์ฉ์ ์ ๋ ฅ ์ฐฝ
- ์ต๋ช ์ฌ์ฉ์: ๋๋ค์๋ง ์ ๋ ฅํ์ฌ ์ฑํ ์ฐธ์ฌ
- ํ์ ์ฌ์ฉ์: ํ์๊ฐ์ /๋ก๊ทธ์ธ ํ ๊ณ ์ ๋๋ค์์ผ๋ก ์ฑํ
- WebSocket (STOMP) - ์ค์๊ฐ ์ฑํ
- Spring Security - ์ธ์ฆ/์ธ๊ฐ
- Mybatis - ๋ฐ์ดํฐ ๊ด๋ฆฌ
- Redis - ์ฑํ
์บ์ฑ ๋ฐ ์ธ์
๊ด๋ฆฌ
- MySQL - ์ฌ์ฉ์/๊ฒฝ๊ธฐ ์ ๋ณด ์ ์ฅ
- Vue 3 + Composition API
- Pinia - ์ํ ๊ด๋ฆฌ
- Vue Router - ๋ผ์ฐํ
- Socket.io-client - WebSocket ํต์
- Tailwind CSS/Vuetify - UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ
-- ๊ฒฝ๊ธฐ ์ ๋ณด
games (id, home_team, away_team, game_date, status, stream_url)
-- ์ฌ์ฉ์ ์ ๋ณด
users (id, username, password, nickname, created_at)
-- ์ฑํ
๋ฉ์์ง
chat_messages (id, game_id, user_id, nickname, message, timestamp, is_anonymous)
-- ์ต๋ช
์ธ์
anonymous_sessions (session_id, nickname, game_id, created_at)- ํค๋: ๋ก๊ทธ์ธ/ํ์๊ฐ์ ๋ฒํผ
- ๊ฒฝ๊ธฐ ๋ฆฌ์คํธ ์นด๋ํ ๋ ์ด์์
- ๊ฐ ์นด๋: ํ ์ ๋ณด, ์๊ฐ, ์ฐธ์ฌ์ ์, ์ต๊ทผ ์ฑํ 30๊ฐ
pc
- ์ผ์ชฝ : ๋ฌธ์ ์ค๊ณ
- ์ค๋ฅธ์ชฝ : ์ฑํ ์์ญ
๋ชจ๋ฐ์ผ
- ์๋จ: ์ค๊ณ ์์ (50% ํ๋ฉด)
- ํ๋จ: ์ฑํ ์์ญ (50% ํ๋ฉด)
- ์ฐ์ธก ์ฌ์ด๋๋ฐ: ์ฐธ์ฌ์ ๋ชฉ๋ก (์ต์ )
// Vue.js์์ WebSocket ์ฐ๊ฒฐ
const socket = io('/game-' + gameId)
socket.on('newMessage', (message) => {
messages.value.push(message)
})@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
// STOMP ์๋ํฌ์ธํธ ์ค์
// ์ฑํ
๋ฉ์์ง ๋ธ๋ก์ปค ๊ตฌ์ฑ
}- ๊ธฐ๋ณธ ๊ฒฝ๊ธฐ ๋ชฉ๋ก ํ์
- ๊ฒฝ๊ธฐ๋ณ ์ฑํ ๋ฐฉ ๊ตฌํ
- ์ต๋ช ์ฑํ ๊ธฐ๋ฅ
- ์ค์๊ฐ ๋ฉ์์ง ์ก์์
- ํ์๊ฐ์ /๋ก๊ทธ์ธ ๊ธฐ๋ฅ
- ์ฑํ ํ์คํ ๋ฆฌ ์ ์ฅ
- ์ฌ์ฉ์๋ณ ๋๋ค์ ๊ด๋ฆฌ
- ์ค๊ณ ์์ ์ฐ๋
- ์ฑํ ํํฐ๋ง/์ ๊ณ ๊ธฐ๋ฅ
- ์ด๋ชจํฐ์ฝ/๋ฐ์ ๊ธฐ๋ฅ