Home

Awesome

s-server

Some Small & Smart Servers written in Scala, including a nio server and a small httpd, which also supports websocket(v13 only).

It's targeted for small footprint when running, with extensibility for mulit-threading when processing http requests' business.

s-server uses '@sun.misc.Contended' to kick false sharing off, so run it on jvm-8 with -XX:-RestrictContended if asynchronous responses are needed.

Http parsing and rendering are based on spray, but I tweaked it much for performance and code size.

Note that s-server 3.x is the current supported release, other version is deprecated.

Benchmark

s-server is optimized for tcp services extremely. In TechEmpower Framework Benchmarks (TFB) 2017, s-server got good scores, such as the following:

TechEmpower Framework Benchmarks (TFB) 2017

How to Use It?

Three Examples:

To test the above examples, just type the following command in your sbt console:

  	set unmanagedSourceDirectories in Compile := (unmanagedSourceDirectories in Compile).value ++ (unmanagedSourceDirectories in Test).value
  	set mainClass in Compile := Some("woshilaiceshide.sserver.test.EchoServer")
  	#or set mainClass in Compile := Some("woshilaiceshide.sserver.test.SampleHttpServer")
  	#or set mainClass in Compile := Some("woshilaiceshide.sserver.test.AdvancedHttpServer")
  	stage

How to Build It?

If proxy is needed:

sbt \
    -Dsbt.repository.config=./repositories \
    -Dsbt.override.build.repos=true \
    -Dhttp.proxyHost=${proxy_host} -Dhttp.proxyPort=${proxy_port} -Dhttp.proxyUser=${proxy_user} -Dhttp.proxyPassword=${proxy_password} \
    -Dhttp.nonProxyHosts="localhost|127.0.0.1" \
    -Dhttps.proxyHost=${proxy_host} -Dhttps.proxyPort=${proxy_port} -Dhttps.proxyUser=${proxy_user} -Dhttps.proxyPassword=${proxy_password} \
    -Dhttps.nonProxyHosts="localhost|127.0.0.1" \
    -Dsbt.gigahorse=false \
    -v -d stage

If no proxy is needed:

sbt -Dsbt.repository.config=./repositories -Dsbt.override.build.repos=true -v -d stage

Features

About '100% CPU with epoll'

The previous releases(<= v2.5) of s-server have dealt with 100% CPU with epoll. The main related codes can be seen on this link. Since 3.x, s-server clears out all those codes. So do not run s-server on jdk 6 and 7.

Model

How to Add It to My Projects?

  1. I've published s-server to bintray, you can add the following line in your build.sbt:

    resolvers += "Woshilaiceshide Releases" at "http://dl.bintray.com/woshilaiceshide/maven/"

    libraryDependencies += "woshilaiceshide" %% "s-server" % "3.1" withSources()

  2. build s-server locally using 'sbt publishLocal'.

Real Projects

Optimizations & TODO

JVM Introspection & Debug

Attention Please!

When the input stream is shutdown by the client, the server will read "-1" bytes from the stream. But, "-1" can not determine among "the entire socket is broken" or "just the input is shutdown by peer, but the output is still alive".

I tried much, but did not catch it!

Business codes may "ping" to find out weather the peer is fine, or just shutdown the whole socket in this situation. The key hook is "woshilaiceshide.sserver.nio.ChannelHandler.inputEnded(channelWrapper: NioSocketServer.ChannelWrapper)". In most situations, You can just close the connection