Skip to content

Instantly share code, notes, and snippets.

@pgabara
Last active October 7, 2019 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgabara/a4bd2de00365a6a5636e9294bfc06faa to your computer and use it in GitHub Desktop.
Save pgabara/a4bd2de00365a6a5636e9294bfc06faa to your computer and use it in GitHub Desktop.
Simple server-scoket channel
package app
import zio._
import zio.clock._
import zio.console._
import zio.random._
import zio.nio.channels.{ AsynchronousServerSocketChannel, AsynchronousSocketChannel }
import zio.nio._
import zio.duration._
object Main extends App {
def run(args: List[String]): ZIO[Environment, Nothing, Int] =
Server.start(9002)
.foldM(e => putStrLn("Error: " + e.getMessage) *> ZIO.succeed(1), _ => ZIO.succeed(0))
}
object Server {
def start(port: Int): RIO[Console with Clock with Random, Unit] =
AsynchronousServerSocketChannel().use(
server =>
for {
socketAddress <- SocketAddress.inetSocketAddress(port)
_ <- server.bind(socketAddress)
_ <- putStrLn("Listening on port: " + port)
_ <- server.accept.reserve.flatMap(accept).forever
} yield ()
)
private def accept(reservation: Reservation[Any, Exception, AsynchronousSocketChannel]) =
reservation.acquire.flatMap { socket =>
socket.read(24, 30.seconds)
.flatMap(chunk => putStrLn("Read chunk: " + chunk.mkString))
.whenM(socket.isOpen)
.forever
.ensuring(reservation.release(Exit.Success(0)) *> putStrLn("Connection closed."))
.catchAll(e => putStrLn("Connection closed due to: " + e.getMessage))
.fork
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment