Created
February 19, 2012 22:05
-
-
Save vincentchu/1866111 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.actors.Actor | |
import scala.actors._ | |
import scala.collection.mutable.Map | |
import java.io._ | |
import java.net.{InetAddress,ServerSocket,Socket,SocketException} | |
class Coordinator extends Actor { | |
var clients = Map[String, Client]() | |
var numClients = 0 | |
def pushClient(client:Client) { | |
clients(client.id) = client | |
numClients += 1 | |
println("Pushed client " + client.id + " Total connected: " + numClients) | |
} | |
def removeClient(client:Client) { | |
clients.remove(client.id) | |
numClients -= 1 | |
println("Removed client " + client.id + " Total connected: " + numClients) | |
} | |
def handleMsg(data:Map[String, String]) { | |
val clientId = data("id") | |
clients.keys.foreach( k => { | |
if (k != clientId) | |
clients(k) ! data | |
}) | |
} | |
def act { | |
loop { | |
react { | |
case data:Map[String, String] => handleMsg(data) | |
case "_" => {} | |
} | |
} | |
} | |
} | |
class PortListener(val port:Int, val coordinator:Coordinator) extends Actor { | |
def act { | |
println("PortListener: listening on " + port) | |
val listener = new ServerSocket(port) | |
loop { | |
val client = new Client(listener.accept(), coordinator) | |
client.start | |
coordinator.pushClient(client) | |
} | |
} | |
} | |
class Client(val socket:Socket, val chatCoord:Coordinator) extends Actor { | |
var id = scala.util.Random.nextInt(1000000).toString | |
var name = "anon" + scala.util.Random.nextInt(1000000).toString | |
val out = new PrintWriter(socket.getOutputStream(), true) | |
val in = new BufferedReader( new InputStreamReader(socket.getInputStream())) | |
val col = 1 + scala.util.Random.nextInt(7) | |
def log(msg:String) { | |
println("Client " + id + ": " + msg) | |
} | |
def write(msg:String) { | |
out.println(msg); out.flush | |
} | |
def handleMesg(data:Map[String, String]) { | |
val startCode = "\033[3" + data("col") + ";1m" | |
write(startCode + ">> " + data("id") + ":\033[0m " + data("msg")) | |
} | |
def act { | |
write("\033[37;1mConnected to chatserver ... There are " + chatCoord.numClients + " connected clients\033[0m") | |
loop { | |
if (in.ready) { | |
val msg = in.readLine | |
log("Socket read " + msg) | |
if (msg.startsWith("/name")) | |
name = msg.split(" ").last | |
else | |
chatCoord ! Map( | |
"id" -> id, | |
"name" -> name | |
"msg" -> msg, | |
"col" -> col.toString | |
) | |
} | |
reactWithin(100) { | |
case data:Map[String, String] => handleMesg(data) | |
case _ => {} | |
} | |
} | |
} | |
} | |
println("STARTING") | |
val chatCoord = new Coordinator | |
val listener = new PortListener(8080, chatCoord) | |
chatCoord.start | |
listener.start |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment