diff options
| author | lonkaars <l.leblansch@gmail.com> | 2021-03-19 18:45:23 +0100 | 
|---|---|---|
| committer | lonkaars <l.leblansch@gmail.com> | 2021-03-19 18:45:23 +0100 | 
| commit | 38f22113d3d97f99125ebdafba4aedafc5780987 (patch) | |
| tree | 3c6eb7848bda780bed34c68409825348daeeeabc | |
| parent | 8c5618c497045a87cd2d9c663e695aeab95d24d7 (diff) | |
socket context + use socket.io's rooms feature for client seperation
| -rw-r--r-- | api/events.py | 28 | ||||
| -rw-r--r-- | api/game/random.py | 4 | ||||
| -rw-r--r-- | api/game/socket.py | 26 | ||||
| -rw-r--r-- | components/socketContext.tsx | 12 | ||||
| -rw-r--r-- | pages/_app.tsx | 5 | ||||
| -rw-r--r-- | pages/index.tsx | 8 | 
6 files changed, 63 insertions, 20 deletions
| diff --git a/api/events.py b/api/events.py new file mode 100644 index 0000000..b7b8ab4 --- /dev/null +++ b/api/events.py @@ -0,0 +1,28 @@ +from flask import Blueprint, request, make_response +from flask_socketio import SocketIO, emit, Namespace, join_room, leave_room, rooms +from socket_io import io +from auth.login_token import token_login +from http import cookies + +from game.cleanup import set_interval +import time + +def get_token(environ): +    cookie = environ.get("HTTP_COOKIE") +    if not cookie: return None +    parsed = cookies.SimpleCookie() +    parsed.load(cookie) +    token = parsed.get("token") +    if not token: return None +    return token.value + +@io.on("connect") +def connect(): +    token = get_token(request.environ) +    if not token: return + +    user_id = token_login(token) +    if not user_id: return + +    join_room(user_id) + diff --git a/api/game/random.py b/api/game/random.py index bc9518d..8d730ad 100644 --- a/api/game/random.py +++ b/api/game/random.py @@ -4,7 +4,7 @@ from randid import new_uuid  import time  import json  import random -from game.socket import io, game, games, listeners +from game.socket import io, game, games  from auth.login_token import token_login  random_game = Blueprint('random', __name__) @@ -41,7 +41,7 @@ def index():          players = cursor.execute("select player_1_id, player_2_id from games where game_id = ?", [game_id]).fetchone()          games[game_id] = game(game_id, io, players[0], players[1]) -        games[game_id].send("gameStart", ""); +        io.emit("gameStart", room=game_id)          player_1 = False          game_started = True diff --git a/api/game/socket.py b/api/game/socket.py index 0318e0b..6f1112a 100644 --- a/api/game/socket.py +++ b/api/game/socket.py @@ -1,5 +1,5 @@  from flask import Blueprint, request, make_response -from flask_socketio import SocketIO, emit, Namespace +from flask_socketio import SocketIO, emit, Namespace, join_room  from game.voerbak_connector import bord  from auth.login_token import token_login  from db import cursor, connection @@ -8,7 +8,6 @@ import json  from socket_io import io  games = {} -listeners = {}  class game:      def __init__(self, game_id, io, player_1_id, player_2_id): @@ -18,18 +17,13 @@ class game:          self.player_1_id = player_1_id          self.player_2_id = player_2_id -    def send(self, message, data): -        if not self.game_id in listeners: return -        for listener in listeners[self.game_id]: -            self.io.emit(message, data, room=listener) -      def move(self, user_id, column):          if user_id != self.player_1_id and user_id != self.player_2_id: return          move = self.player_1_id if self.board.player_1 else self.player_2_id          if user_id != move: return          self.board.drop_fisje(column) -        self.send("fieldUpdate", { "field": self.board.board }) +        io.emit("fieldUpdate", { "field": self.board.board }, room=self.game_id)          now = int( time.time() * 1000 )          cursor.execute("update games set last_activity = ?, moves = moves || ? || ',' where game_id = ?", [now, column, self.game_id]) @@ -40,18 +34,18 @@ class game:              if not self.board.board_full:                  winner = self.board.board[int(self.board.win_positions[0][0])]                  outcome = "w" if winner == "2" else "l" -            self.send("finish", { +            io.emit("finish", {                  "winPositions": self.board.win_positions,                  "boardFull": self.board.board_full -                }) +                }, room=self.game_id)              self.close("finished", outcome)              return -        self.send("turnUpdate", { "player1": self.board.player_1 }) +        io.emit("turnUpdate", { "player1": self.board.player_1 }, room=self.game_id)      def resign(self):          self.board.kill_voerbak() -        self.send("resign", "") +        io.emit("resign", room=self.game_id)          self.close("resign", "d")      def close(self, new_status, outcome): @@ -71,7 +65,6 @@ class game:          connection.commit()          games.pop(self.game_id) -        listeners.pop(self.game_id)  @io.on("newMove")  def new_move(data): @@ -102,7 +95,8 @@ def resign(data):  @io.on("registerGameListener")  def register_game_listener(data): -    if not data["game_id"]: return -    if not data["game_id"] in listeners: listeners[data["game_id"]] = set() -    listeners[data["game_id"]].add(request.sid) +    game_id = data.get("game_id") +    if not game_id: return + +    join_room(game_id) diff --git a/components/socketContext.tsx b/components/socketContext.tsx new file mode 100644 index 0000000..f493d73 --- /dev/null +++ b/components/socketContext.tsx @@ -0,0 +1,12 @@ +import { ReactNode, createContext } from 'react'; +import { io as socket, Socket } from 'socket.io-client'; + +export var SocketContext = createContext<{ io?: Socket }>({}); +export function SocketContextWrapper(props: { children?: ReactNode }) { +	var io = socket(); + +	return <SocketContext.Provider value={{ io }}> +		{ props.children } +	</SocketContext.Provider> +} + diff --git a/pages/_app.tsx b/pages/_app.tsx index 1561eda..bfde0d7 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,6 +1,7 @@  import Head from 'next/head';  import { PreferencesContextWrapper } from '../components/preferencesContext';  import { ToastContextWrapper } from '../components/toast'; +import { SocketContextWrapper } from '../components/socketContext';  import '../styles/global.css';  import '../styles/dark.css'; @@ -26,7 +27,9 @@ export default function VierOpEenRijWebsite({ Component, pageProps }) {  		</Head>  		<PreferencesContextWrapper>  			<ToastContextWrapper> -				<Component {...pageProps}/> +				<SocketContextWrapper> +					<Component {...pageProps}/> +				</SocketContextWrapper>  			</ToastContextWrapper>  		</PreferencesContextWrapper>  	</div> diff --git a/pages/index.tsx b/pages/index.tsx index 266a3f4..dfb14e6 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,6 +1,7 @@ -import { CSSProperties, useState, useEffect } from 'react'; +import { CSSProperties, useState, useEffect, useContext } from 'react';  import axios from 'axios';  import { userInfo, userGameTotals, userGames } from '../api/api'; +import { SocketContext } from '../components/socketContext';  import { NavBar } from '../components/navbar';  import { CenteredPage, PageTitle } from '../components/page'; @@ -120,6 +121,11 @@ export default function HomePage() {  	var server = typeof window === "undefined";  	var loggedIn = !server && document.cookie.includes("token"); +	var { io } = useContext(SocketContext); +	useEffect(() => { +		io.on("connect", () => { console.log("gert") }); +	}, []); +  	var [userInfo, setUserInfo] = useState<userInfo>();  	var [gameInfo, setGameInfo] = useState<userGames>(); |