All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rc_2.10.0.2.0.source-code.Client.scala Maven / Gradle / Ivy

package org.conbere.irc

import java.net.InetSocketAddress
import com.typesafe.scalalogging.log4j.Logging

import akka.actor._
import akka.util.{ ByteString, ByteStringBuilder }

import Tokens._
import ControlChars._
import Messages._

object Client extends Logging {
  def start(serverName:String, port:Int, responder:Bot) = {
    ActorSystem().actorOf(Props(new Client(serverName, port, responder)))
  }
}

class Client(serverName:String, port:Int, responder:Bot)
extends Actor with Logging {
  val state = IO.IterateeRef.Map.async[IO.Handle]()(context.dispatcher)
  val address = new InetSocketAddress(serverName, port)

  def utf8(bytes:ByteString) =
    bytes.decodeString("UTF-8").trim

  override def preStart {
    println("Connecting to: " + address)
    IOManager(context.system).connect(address)
  }

  def parseMessage(str:String) =
    Parser.apply(str) match {
      case Parser.Success(message, _) =>
        println("Received: " + message)
        Some(message)
      case _ =>
        logger.error("Could not parse: " + str)
        None
    }

  def writeResponseSocket(socket:IO.SocketHandle)(response:Option[Response]) = {
    response match {
      case Some(response) =>
        println("Response: " + utf8(response.byteString))
        socket.write((new ByteStringBuilder ++= response.byteString ++= CRLF).result)
      case _ =>
        // no response
    }
  }

  def receive = {
    case IO.Connected(socket, address) =>
      val writeResponse = writeResponseSocket(socket) _

      writeResponse(responder.onConnect)

      state(socket).flatMap(_ =>
        IO.repeat {
          IO.takeUntil(CRLF).map { in =>
            parseMessage(utf8(in)) match {
              case Some(message) =>
                if (responder.respondTo.isDefinedAt(message)) {
                  writeResponse(responder.respondTo(message))
                }
              case None =>
                // do nothing
            }
          }
        }
      )

    case IO.Read(socket, bytes) =>
      state(socket)(IO.Chunk(bytes))

    case IO.Closed(socket, cause) =>
      state(socket)(IO.EOF)
      state -= socket
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy