Skip to content

Commit

Permalink
update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
veebs committed Jun 16, 2012
1 parent 9f644d0 commit 6cfab6f
Show file tree
Hide file tree
Showing 18 changed files with 179 additions and 177 deletions.
172 changes: 50 additions & 122 deletions README.md
@@ -1,134 +1,64 @@
# SOCKO

An embedded [Scala](http://www.scala-lang.org/) web server powered by
Socko is an embedded [Scala](http://www.scala-lang.org/) web server powered by
[Netty](http://netty.io/) networking and [Akka](http://akka.io/) processing.

## Background
We are currently working on a HTML5 style app called MashupBots.

We wanted an open source, lightweight and embeddable Scala web server that can serve static files and support RESTful APIs to our business logic implemented in Akka.

We do not need a web application framework: server side templating, caching, session management, etc.

We couldn't find a web server that exactly meets our requirements, so we decided to write one.

We hope you find it as useful as we do.

## What is Socko?

Socko is:

* Intended for Akka developers
* who wish to expose their Akka actors as REST endpoints
* who wish to serve static files and/or HTML 5 applications from the same web server hosting
their REST endpoints

* Embedded
* Socko runs within your Scala application.
* Routing DSL like [Unfilted](http://unfiltered.databinder.net/Unfiltered.html) and
[Play2 Mini](https://github.com/typesafehub/play2-mini). Route by HTTP method, host, path and querystring.
See [example](https://github.com/mashupbots/socko/blob/master/socko-examples/src/main/scala/org/mashupbots/socko/examples/routes/RouteApp.scala).
* Configurable from inside your code and/or via settings in Akka's configuration file.

* Lightweight (assuming you are already using Akka)
* ~1,300 lines of Scala code (and ~2,600 lines of Java code which will be removed once Akka
moves to the upcoming Netty 4.0).
* Socko has no external dependencies outside Akka 2.0 Remote (which includes Netty).

* Fast-ish
* Socko handles and processes incoming HTTP requests in an asynchronous and event driven manner thanks to
Netty and Akka.
* Initial benchmarking [results](http://sockoweb.org/2012/04/22/benchmark.html)

* Supportive of HTTP and HTML5 Standards
* HTTP/S and WebSockets
* HTTP compression
* HTTP headers
* Decoding HTTP POST, file uploads and query strings

* Open Source
* [Apache 2 license](http://www.apache.org/licenses/LICENSE-2.0)


## What Socko is NOT

* Socko is not a standalone web server. It must be embedded within your application.

* Socko is not a servlet container. It will not run your servlet or JSP pages.

* Socko is not a web application or MVC framework like Lift or Play. It does not perform server side
HTML templating. We use client side javascript libraries like EmberJS and BackboneJS instead.


## Quick Start

```scala
object HelloApp extends Logger {

//
// STEP #1 - Define actors and start Akka
// See `HelloProcessor` below
//
val actorSystem = ActorSystem("HelloExampleActorSystem")

//
// STEP #2 - Define routes.
//
val routes = Routes({
case GET(httpRequest) => {
actorSystem.actorOf(Props[HelloProcessor]) ! httpRequest
**Please see our [web site](http://sockoweb.org/) for documentaiton and more information**

## A quick example

object HelloApp extends Logger {
//
// STEP #1 - Define Actors and Start Akka
// See `HelloHandler`
//
val actorSystem = ActorSystem("HelloExampleActorSystem")

//
// STEP #2 - Define Routes
// Dispatch all HTTP GET events to a newly instanced `HelloHandler` actor for processing.
// `HelloHandler` will `stop()` itself after processing each request.
//
val routes = Routes({
case GET(request) => {
actorSystem.actorOf(Props[HelloHandler]) ! request
}
})

//
// STEP #3 - Start and Stop Socko Web Server
//
def main(args: Array[String]) {
val webServer = new WebServer(WebServerConfig(), routes, actorSystem)
webServer.start()

Runtime.getRuntime.addShutdownHook(new Thread {
override def run { webServer.stop() }
})

System.out.println("Open your browser and navigate to http://localhost:8888")
}
}
})

//
// STEP #3 - Start and Stop web server.
//
def main(args: Array[String]) {
val webServer = new WebServer(WebServerConfig(), routes)
webServer.start()

Runtime.getRuntime.addShutdownHook(new Thread {
override def run { webServer.stop() }
})

System.out.println("Open your browser and navigate to http://localhost:8888");
}
}

class HelloProcessor extends Actor {
def receive = {
case request: HttpRequestProcessingContext =>
request.writeResponse("Hello from Socko (" + new Date().toString + ")")
context.stop(self)
}
}
```


## Developer Information

### Getting the Source

Get the source code from github

$ git clone git@github.com:mashupbots/socko.git
$ cd socko

### Run Unit Tests

$ sbt test

### Run Examples
/**
* Hello processor writes a greeting and stops.
*/
class HelloHandler extends Actor {
def receive = {
case event: HttpRequestEvent =>
event.response.write("Hello from Socko (" + new Date().toString + ")")
context.stop(self)
}
}

$ sbt
> project socko-examples
> run

### Editing the Source Code
## Editing the Source Code

* We are currently using [Eclipse 3.7 Indigo](http://www.eclipse.org/downloads/packages/eclipse-ide-javascript-web-developers/indigosr2)
with [Scala IDE nightly build](http://scala-ide.org/download/nightly.html)

* We are currently using Scala 2.9.1 and JDK7. You can also use JDK6 but SPDY will not be supported.

* Generate eclipse project files: `sbt eclispse`

* Start `Eclipse`
Expand All @@ -142,12 +72,10 @@ Get the source code from github

* To run the scalatest unit test cases, just right click on a test class file and select `Run As JUnit Test`.

### Getting Help
## Getting Help

If you have a question or need help, please open a ticket in our [Issues Register] (https://github.com/mashupbots/socko/issues).



## Links

* [Web Site](http://sockoweb.org/)
Expand Down
2 changes: 1 addition & 1 deletion project/build.scala
Expand Up @@ -18,7 +18,7 @@ object SockoBuild extends Build {
lazy val defaultSettings = Defaults.defaultSettings ++ Seq(
// Info
organization := "org.mashupbots.socko",
version := "0.2.0-SNAPSHOT",
version := "0.2.0",

// Repositories
resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/",
Expand Down
Binary file not shown.
Binary file added sbt/npn-boot-1.1.0.v20120525.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion sbt/sbt
@@ -1 +1 @@
java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -Xbootclasspath/p:`dirname $0`/npn-boot-8.1.2.v20120308.jar -jar `dirname $0`/sbt-launch-0.11.3.jar "$@"
java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -Xbootclasspath/p:`dirname $0`/npn-boot-1.0.0.v20120402.jar -jar `dirname $0`/sbt-launch-0.11.3.jar "$@"
47 changes: 46 additions & 1 deletion socko-docs/docs/guides/user_guide.markdown
Expand Up @@ -27,6 +27,7 @@ StaticResourceRequestClass: <code><a href="../api/#org.mashupbots.socko.handler.
- [Configuration](#Configuration)
- [Serving Static Content](#StaticContent)
- [Web Sockets](#WebSockets)
- [SPDY](#SPDY)
- [Web Logs](#WebLogs)
- [Code Examples](https://github.com/mashupbots/socko/tree/master/socko-examples/src/main/scala/org/mashupbots/socko/examples)

Expand Down Expand Up @@ -68,7 +69,8 @@ The default dispatcher is optimized for non blocking code. If your code blocks t
database and/or file system, then it is advisable to configure Akka to use dispatchers based on thread pools.

### Socko Events
{{ page.SockoEventClass }} is used to read incoming and write outgoing data.

A {{ page.SockoEventClass }} is used to read incoming and write outgoing data.

Two ways to achieve this are:

Expand Down Expand Up @@ -565,6 +567,10 @@ Common settings are:

Optional HTTP request settings.

- `tcp`

Optional TCP/IP settings.

Refer to the api documentation of {{ page.WebServerConfigClass }} for all settings.

Configuration can be changed in [code](https://github.com/mashupbots/socko/blob/master/socko-examples/src/main/scala/org/mashupbots/socko/examples/config/CodedConfigApp.scala)
Expand Down Expand Up @@ -715,6 +721,45 @@ If you wish to push or broadcast messages to a group of web socket connections,
See the example web socket [ChatApp](https://github.com/mashupbots/socko/blob/master/socko-examples/src/main/scala/org/mashupbots/socko/examples/websocket/ChatApp.scala) for usage.




## SPDY <a class="blank" id="SPDY">&nbsp;</a>

[SPDY](http://en.wikipedia.org/wiki/SPDY) is an experimental networking protocol used in speeding up delivery of web
content.

It is currently supported in the Chrome and Firefox (v11+) browsers.

Steps to enabling SPDY:

1. You will need to run with **JDK 7**

2. Setup JVM Bootup classes

SPDY uses a special extension to TLS/SSL called [Next Protocol Negotiation](http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00).
This is not currently supported by Java JDK. However, the Jetty team has kindly open sourced their implementation.

Refer to [Jetty NPN](http://wiki.eclipse.org/Jetty/Feature/NPN#Versions) for the correct version and download it from
the [maven repository](http://repo2.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/).

Add the JAR to your JVM boot parameters: `-Xbootclasspath/p:/path/to/npn-boot-1.0.0.v20120402.jar`.

3. Set Web Server Configuration

You will need to turn on SSL and enable SPDY in your configuration.

val keyStoreFile = new File(contentDir, "testKeyStore")
val keyStoreFilePassword = "password"
val sslConfig = SslConfig(keyStoreFile, keyStoreFilePassword, None, None)
val httpConfig = HttpConfig(spdyEnabled = true)
val webServerConfig = WebServerConfig(hostname="0.0.0.0", webLog = Some(WebLogConfig()), ssl = Some(sslConfig), http = httpConfig)
val webServer = new WebServer(webServerConfig, routes, actorSystem)
webServer.start()





## Web Logs <a class="blank" id="WebLogs">&nbsp;</a>

Socko supports 3 web log formats:
Expand Down
Expand Up @@ -47,8 +47,8 @@ import akka.routing.FromConfig
*
* To run this example you need to:
* - use JDK 7
* - add `-Xbootclasspath/p:/path/to/sbt/npn-boot-8.1.2.v20120308.jar` to your JVM start up parameter
* - browser using Chrome
* - add `-Xbootclasspath/p:/path/to/sbt/npn-boot-VERSION.jar` to your JVM start up parameter
* - browse using Chrome
*
* For an example, see `/socko/sbt/sbt` file.
*/
Expand Down Expand Up @@ -159,12 +159,12 @@ object SpdyApp extends Logger {
System.out.println("")
System.out.println("Make sure that you:")
System.out.println("1. Are using JDK 7")
System.out.println("2. Have added `-Xbootclasspath/p:/path/to/sbt/npn-boot-8.1.2.v20120308.jar` to your JVM start up parameter")
System.out.println("2. Have added `-Xbootclasspath/p:/path/to/sbt/npn-boot-VERSION.jar` to your JVM start up parameter")
System.out.println(" Refer to /socko/sbt/sbt for an example")
System.out.println("3. Browser using Chrome")
System.out.println("")
System.out.println("3. Browse using Chrome")
System.out.println("")
System.out.println("Check your SPDY session at chrome://net-internals/#spdy")
System.out.println("")
}

/**
Expand Down
@@ -1,4 +1,7 @@
/*
* Sourced from
* https://github.com/eclipse/jetty.project/blob/master/jetty-npn/src/main/java/org/eclipse/jetty/npn/NextProtoNego.java
*
* Copyright (c) 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -87,7 +90,8 @@
* </pre>
* <p>There is no need to unregister {@link SSLSocket} or {@link SSLEngine} instances, as they
* are kept in a {@link WeakHashMap} and will be garbage collected when the application does not
* hard reference them anymore.</p>
* hard reference them anymore. However, methods to explicitly unregister {@link SSLSocket} or
* {@link SSLEngine} instances are provided.</p>
* <p>In order to help application development, you can set the {@link NextProtoNego#debug} field
* to {@code true} to have debug code printed to {@link System#err}.</p>
*/
Expand All @@ -109,6 +113,7 @@ private NextProtoNego()
*
* @param socket the socket to register with the provider
* @param provider the provider to register with the socket
* @see #remove(SSLSocket)
*/
public static void put(SSLSocket socket, Provider provider)
{
Expand All @@ -124,11 +129,24 @@ public static Provider get(SSLSocket socket)
return objects.get(socket);
}

/**
* <p>Unregisters the given SSLSocket.</p>
*
* @param socket the socket to unregister
* @return the provider registered with the socket
* @see #put(SSLSocket, Provider)
*/
public static Provider remove(SSLSocket socket)
{
return objects.remove(socket);
}

/**
* <p>Registers a SSLEngine with a provider.</p>
*
* @param engine the engine to register with the provider
* @param provider the provider to register with the engine
* @see #remove(SSLEngine)
*/
public static void put(SSLEngine engine, Provider provider)
{
Expand All @@ -145,6 +163,18 @@ public static Provider get(SSLEngine engine)
return objects.get(engine);
}

/**
* <p>Unregisters the given SSLEngine.</p>
*
* @param engine the engine to unregister
* @return the provider registered with the engine
* @see #put(SSLEngine, Provider)
*/
public static Provider remove(SSLEngine engine)
{
return objects.remove(engine);
}

/**
* <p>Base, empty, interface for providers.</p>
*/
Expand Down
Expand Up @@ -18,7 +18,7 @@ package org.mashupbots.socko.events
import akka.actor.ActorRef

/**
* Web Socket configuration used by [[org.mashupbots.socko.events.WebSocketFrameEvent]
* Web Socket configuration used by [[org.mashupbots.socko.events.WebSocketFrameEvent]]
*
* @param serverName Name of this instance of the Socko Web Server
* @param webLogWriter Actor to which web log events to be sent
Expand Down

0 comments on commit 6cfab6f

Please sign in to comment.