Better round sockets

pull/1/merge
Thibault Duplessis 2012-05-18 12:16:17 +02:00
parent 502235f08a
commit 8c3705a7d1
8 changed files with 694 additions and 669 deletions

View File

@ -28,18 +28,6 @@ object App extends LilaController {
username = get("username"))
}
def gameSocket(gameId: String, color: String) =
WebSocket.async[JsValue] { implicit req
implicit val ctx = Context(req, None)
env.round.socket.join(
uidOption = get("uid"),
username = get("username"),
gameId = gameId,
colorName = color,
versionOption = getInt("version"),
playerId = get("playerId")).unsafePerformIO
}
def abort(fullId: String) = performAndRedirect(fullId, hand.abort)
def resign(fullId: String) = performAndRedirect(fullId, hand.resign)

View File

@ -2,14 +2,35 @@ package controllers
import lila._
import views._
import http.Context
import game.Pov
import socket.Util.connectionFail
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.iteratee._
object Round extends LilaController {
val gameRepo = env.game.gameRepo
val socket = env.round.socket
def websocketWatcher(gameId: String, color: String) =
WebSocket.async[JsValue] { req
implicit val ctx = reqToCtx(req)
socket.joinWatcher(
gameId, color, getInt("version"), get("uid"), get("username")
).unsafePerformIO
}
def websocketPlayer(fullId: String) =
WebSocket.async[JsValue] { req
implicit val ctx = reqToCtx(req)
socket.joinPlayer(
fullId, getInt("version"), get("uid"), get("username")
).unsafePerformIO
}
def watcher(gameId: String, color: String) = Open { implicit ctx
IOption(gameRepo.pov(gameId, color)) { pov
html.round.watcher(pov, version(pov.gameId))

View File

@ -35,7 +35,8 @@ final class RoundEnv(
)), name = ActorGameHubMaster)
lazy val socket = new Socket(
getGame = gameRepo.game,
getWatcherPov = gameRepo.pov,
getPlayerPov = gameRepo.pov,
hand = hand,
hubMaster = hubMaster,
messenger = messenger)

View File

@ -14,13 +14,15 @@ import play.api.Play.current
import scalaz.effects._
import game.{ DbGame, PovRef }
import game.{ Pov, PovRef }
import chess.Color
import socket.{ Util, Ping, Quit }
import socket.{ Ping, Quit }
import socket.Util.connectionFail
import implicits.RichJs._
final class Socket(
getGame: String IO[Option[DbGame]],
getWatcherPov: (String, String) IO[Option[Pov]],
getPlayerPov: String IO[Option[Pov]],
hand: Hand,
val hubMaster: ActorRef,
messenger: Messenger) {
@ -77,37 +79,48 @@ final class Socket(
case _
}
def join(
uidOption: Option[String],
username: Option[String],
def joinWatcher(
gameId: String,
colorName: String,
version: Option[Int],
uid: Option[String],
username: Option[String]): IO[SocketPromise] = getWatcherPov(gameId, colorName) map {
join(_, false, version, uid, username)
}
def joinPlayer(
fullId: String,
version: Option[Int],
uid: Option[String],
username: Option[String]): IO[SocketPromise] = getPlayerPov(fullId) map {
join(_, true, version, uid, username)
}
private def join(
povOption: Option[Pov],
owner: Boolean,
versionOption: Option[Int],
playerId: Option[String]): IO[SocketPromise] =
getGame(gameId) map { gameOption
val promise: Option[SocketPromise] = for {
game gameOption
color Color(colorName)
version versionOption
uid uidOption
} yield (for {
hub hubMaster ? GetHub(gameId) mapTo manifest[ActorRef]
socket hub ? Join(
uid = uid,
username = username,
version = version,
color = color,
owner = (playerId flatMap game.player).isDefined
) map {
case Connected(member) (
Iteratee.foreach[JsValue](
controller(hub, uid, member, PovRef(gameId, member.color))
) mapDone { _
hub ! Quit(uid)
},
member.channel)
}
} yield socket).asPromise
promise | Util.connectionFail
}
uidOption: Option[String],
username: Option[String]): SocketPromise =
((povOption |@| uidOption |@| versionOption) apply {
(pov: Pov, uid: String, version: Int)
(for {
hub hubMaster ? GetHub(pov.gameId) mapTo manifest[ActorRef]
socket hub ? Join(
uid = uid,
username = username,
version = version,
color = pov.color,
owner = owner
) map {
case Connected(member) (
Iteratee.foreach[JsValue](
controller(hub, uid, member, PovRef(pov.gameId, member.color))
) mapDone { _
hub ! Quit(uid)
},
member.channel)
}
} yield socket).asPromise: SocketPromise
}) | connectionFail
}

View File

@ -19,6 +19,7 @@
@round.layout(title = title, goodies = goodies) {
<div class="lichess_game clearfix lichess_player_@color not_spectator"
data-socket-url="@routes.Round.websocketPlayer(fullId)"
data-table-url="@routes.Round.table(gameId, color.name, fullId)"
data-players-url="@routes.Round.players(gameId)">
<div class="lichess_board_wrap">

View File

@ -45,6 +45,7 @@
@round.layout(title = title, goodies = goodies) {
<div class="lichess_game clearfix lichess_player_@color"
data-socket-url="@routes.Round.websocketWatcher(gameId, color.name)"
data-table-url="@routes.Round.table(gameId, color.name, fullId)"
data-players-url="@routes.Round.players(gameId)">
<div class="lichess_board_wrap">

View File

@ -5,6 +5,8 @@ GET /games/all controllers.Game.all(page: Int ?= 1)
GET /games/checkmate controllers.Game.checkmate(page: Int ?= 1)
# Round
GET /socket/$gameId<[\w\-]{8}>/$color<white|black> controllers.Round.websocketWatcher(gameId: String, color: String)
GET /socket/$fullId<[\w\-]{12}> controllers.Round.websocketPlayer(fullId: String)
GET /$gameId<[\w\-]{8}> controllers.Round.watcher(gameId: String, color: String = "white")
GET /$gameId<[\w\-]{8}>/$color<white|black> controllers.Round.watcher(gameId: String, color: String)
GET /$fullId<[\w\-]{12}> controllers.Round.player(fullId: String)
@ -58,7 +60,6 @@ GET /wiki controllers.Wiki.home
# App Public API
GET /socket controllers.App.socket
GET /socket/:gameId/:color controllers.App.gameSocket(gameId: String, color: String)
GET /ai controllers.Ai.run

File diff suppressed because it is too large Load Diff