Skip to content

Instantly share code, notes, and snippets.

@vincentchu
Created February 19, 2012 22:05
Show Gist options
  • Save vincentchu/1866111 to your computer and use it in GitHub Desktop.
Save vincentchu/1866111 to your computer and use it in GitHub Desktop.
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