Netty-based HTTP server implementation for the Play Framework providing high-performance, asynchronous HTTP processing with WebSocket support.
—
Cake pattern components for building and configuring Netty servers with dependency injection support and modular architecture.
Provides a cake pattern trait for building complete server applications with all necessary dependencies.
/**
* Cake pattern trait providing NettyServer with dependencies
* Mix in with application components to create a complete server
*/
trait NettyServerComponents {
/** Server configuration - override to customize */
lazy val serverConfig: ServerConfig = ServerConfig()
/** The NettyServer instance - automatically configured and started */
lazy val server: NettyServer = {
Play.start(application)
new NettyServer(serverConfig, ApplicationProvider(application), serverStopHook)
}
/** Application environment */
lazy val environment: Environment = Environment.simple(mode = serverConfig.mode)
/** Optional source mapper for development */
lazy val sourceMapper: Option[SourceMapper] = None
/** Web commands for development tools */
lazy val webCommands: WebCommands = new DefaultWebCommands
/** Application configuration */
lazy val configuration: Configuration = Configuration(ConfigFactory.load())
/** Must be implemented - the Play application to serve */
def application: Application
/** Optional hook called when server stops */
def serverStopHook: () => Future[Unit] = () => Future.successful(())
}Usage Examples:
import play.core.server.NettyServerComponents
import play.api.{Application, BuiltInComponents}
import play.api.routing.Router
import play.api.mvc._
// Create a complete server application
class MyServerApp extends NettyServerComponents with BuiltInComponents {
// Override server configuration
override lazy val serverConfig = ServerConfig(
port = Some(9000),
mode = play.api.Mode.Prod
)
// Define the application
lazy val application = new DefaultApplication(
environment,
applicationLifecycle,
injector,
configuration,
requestFactory,
httpErrorHandler
)
// Define routes
lazy val router = Router.from {
case GET -> Root / "health" => Action { Ok("OK") }
case GET -> Root / "info" => Action {
Ok(s"Server running on ${server.mainAddress}")
}
}
// Custom stop hook
override def serverStopHook = () => {
println("Server shutting down...")
Future.successful(())
}
}
// Start the server
val serverApp = new MyServerApp
// Server starts automatically via lazy val
println(s"Server started on port ${serverApp.server.httpPort}")Server provider implementation for creating NettyServer instances in different contexts.
/**
* Creates NettyServer instances from provider context
*/
class NettyServerProvider extends ServerProvider {
/**
* Create NettyServer from context
* @param context Provider context with configuration and application
* @return Configured NettyServer instance
*/
def createServer(context: ServerProvider.Context): NettyServer
}
/**
* Context for server providers
* @param config Server configuration
* @param appProvider Application provider
* @param actorSystem Actor system for the server
* @param stopHook Shutdown callback
*/
case class ServerProvider.Context(
config: ServerConfig,
appProvider: ApplicationProvider,
actorSystem: akka.actor.ActorSystem,
stopHook: () => Future[Unit]
)Usage Examples:
import play.core.server.{NettyServerProvider, ServerProvider}
// Create provider
val provider = new NettyServerProvider
// Create context
val context = ServerProvider.Context(
config = ServerConfig(port = Some(8080)),
appProvider = ApplicationProvider(myApp),
actorSystem = myActorSystem,
stopHook = () => Future.successful(())
)
// Create server via provider
val server = provider.createServer(context)Integrate NettyServerComponents with Play's built-in components for complete applications.
// Combine with BuiltInComponents for full Play stack
trait BuiltInComponents {
def environment: Environment
def configuration: Configuration
def applicationLifecycle: ApplicationLifecycle
def httpErrorHandler: HttpErrorHandler
// ... other built-in components
}Usage Examples:
import play.api.BuiltInComponents
import play.api.routing.Router
import play.filters.HttpFiltersComponents
// Complete application with filters and built-ins
class ProductionServer extends NettyServerComponents
with BuiltInComponents
with HttpFiltersComponents {
override lazy val serverConfig = ServerConfig(
port = Some(sys.env.get("PORT").map(_.toInt).getOrElse(9000)),
mode = play.api.Mode.Prod
)
// Router with application logic
lazy val router = Router.from {
case GET -> Root / "api" / "users" => userController.list
case POST -> Root / "api" / "users" => userController.create
case GET -> Root / "api" / "users" / Long(id) => userController.show(id)
}
// Application with all components wired
lazy val application = Application(
environment,
applicationLifecycle,
injector,
configuration,
requestFactory,
httpErrorHandler
)
// Custom controllers and services
lazy val userController = new UserController(userService)
lazy val userService = new UserService(database)
lazy val database = new DatabaseService(configuration)
}
// Production startup
object ProductionMain extends App {
val server = new ProductionServer
println(s"Production server started on ${server.server.mainAddress}")
// Graceful shutdown
sys.addShutdownHook {
server.server.stop()
}
}Environment and configuration management for server components.
/**
* Application environment configuration
* @param rootPath Application root path
* @param classLoader Class loader for the application
* @param mode Application mode (Dev/Test/Prod)
*/
case class Environment(
rootPath: java.io.File,
classLoader: ClassLoader,
mode: Mode
)
object Environment {
/** Create simple environment for given mode */
def simple(
path: java.io.File = new java.io.File("."),
mode: Mode = Mode.Test
): Environment
}
/**
* Application configuration wrapper
*/
case class Configuration(underlying: com.typesafe.config.Config) {
def get[A](path: String)(implicit loader: ConfigLoader[A]): A
def getOptional[A](path: String)(implicit loader: ConfigLoader[A]): Option[A]
// ... other configuration methods
}
object Configuration {
/** Load configuration from reference.conf and application.conf */
def apply(config: com.typesafe.config.Config): Configuration
/** Empty configuration */
val empty: Configuration
}Usage Examples:
import play.api.{Environment, Configuration, Mode}
import com.typesafe.config.ConfigFactory
// Custom environment
val environment = Environment.simple(
path = new java.io.File("/opt/myapp"),
mode = Mode.Prod
)
// Custom configuration
val config = Configuration(ConfigFactory.parseString("""
app.name = "MyApp"
app.version = "1.0.0"
database.url = "jdbc:postgresql://localhost/myapp"
"""))
// Access configuration values
val appName = config.get[String]("app.name")
val dbUrl = config.getOptional[String]("database.url")Install with Tessl CLI
npx tessl i tessl/maven-com-typesafe-play--play-netty-server-2-10