-
Notifications
You must be signed in to change notification settings - Fork 50
/
client_web.py
138 lines (106 loc) · 4.27 KB
/
client_web.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import os
import uuid
import gevent
import redis
from flask import Flask, render_template, redirect, session, url_for, request
from flask_sockets import Sockets
from geventwebsocket.websocket import WebSocket
from poker.channel import ChannelError, MessageFormatError, MessageTimeout
from poker.channel_websocket import ChannelWebSocket
from poker.player import Player
from poker.player_client import PlayerClientConnector
app = Flask(__name__)
app.config["SECRET_KEY"] = "!!_-pyp0k3r-_!!"
app.debug = True
sockets = Sockets(app)
redis_url = os.environ["REDIS_URL"]
redis = redis.from_url(redis_url)
@app.route("/")
def index():
if "player-id" not in session:
return render_template("index.html", template="login.html")
return render_template("index.html",
template="game.html",
player_id=session["player-id"],
player_name=session["player-name"],
player_money=session["player-money"])
@app.route("/join", methods=["POST"])
def join():
name = request.form["name"]
room_id = request.form["room-id"]
session["player-id"] = str(uuid.uuid4())
session["player-name"] = name
session["player-money"] = 1000
session["room-id"] = room_id if room_id else None
return redirect(url_for("index"))
@sockets.route("/poker/texas-holdem")
def texasholdem_poker_game(ws: WebSocket):
return poker_game(ws, "texas-holdem-poker:lobby")
@sockets.route("/poker/traditional")
def traditional_poker_game(ws: WebSocket):
return poker_game(ws, "traditional-poker:lobby")
def poker_game(ws: WebSocket, connection_channel: str):
client_channel = ChannelWebSocket(ws)
if "player-id" not in session:
client_channel.send_message({"message_type": "error", "error": "Unrecognized user"})
client_channel.close()
return
session_id = str(uuid.uuid4())
player_id = session["player-id"]
player_name = session["player-name"]
player_money = session["player-money"]
room_id = session["room-id"]
player_connector = PlayerClientConnector(redis, connection_channel, app.logger)
try:
server_channel = player_connector.connect(
player=Player(
id=player_id,
name=player_name,
money=player_money
),
session_id=session_id,
room_id=room_id
)
except (ChannelError, MessageFormatError, MessageTimeout) as e:
app.logger.error("Unable to connect player {} to a poker5 server: {}".format(player_id, e.args[0]))
else:
# Forwarding connection to the client
client_channel.send_message(server_channel.connection_message)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Game service communication
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def message_handler(channel1, channel2):
# Forward messages received from channel1 to channel2
try:
while True:
message = channel1.recv_message()
if "message_type" in message and message["message_type"] == "disconnect":
raise ChannelError
channel2.send_message(message)
except (ChannelError, MessageFormatError):
pass
greenlets = [
# Forward client messages to the game service
gevent.spawn(message_handler, client_channel, server_channel),
# Forward game service messages to the client
gevent.spawn(message_handler, server_channel, client_channel)
]
def closing_handler(*args, **kwargs):
# Kill other active greenlets
gevent.killall(greenlets, ChannelError)
greenlets[0].link(closing_handler)
greenlets[1].link(closing_handler)
gevent.joinall(greenlets)
try:
client_channel.send_message({"message_type": "disconnect"})
except:
pass
finally:
client_channel.close()
try:
server_channel.send_message({"message_type": "disconnect"})
except:
pass
finally:
server_channel.close()
app.logger.info("player {} connection closed".format(player_id))