Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active December 21, 2015 13:38
Show Gist options
  • Save hodzanassredin/1c739d4e5c684402a266 to your computer and use it in GitHub Desktop.
Save hodzanassredin/1c739d4e5c684402a266 to your computer and use it in GitHub Desktop.
tcplistener benchmark async 4k
// Step 0. Boilerplate to get the paket.exe tool
open System
open System.IO
open System.Net
open System.Net.Sockets
open System.Threading
//open Hopac
module ServerM =
//hopac mode on
// type Async<'a> = Hopac.Job<'a>
// let async = Hopac.JobBuilder()
// let start = Job.Star//Async.Start
//------------------------------
type Socket with
member socket.AsyncAccept() = Async.FromBeginEnd(socket.BeginAccept, socket.EndAccept)
type Server() =
static member Start(hostname:string, ?port) =
let ipAddress = Dns.GetHostEntry(hostname).AddressList.[0]
Server.Start(ipAddress, ?port = port)
static member Start(?ipAddress, ?port) =
let ipAddress = defaultArg ipAddress IPAddress.Any
let port = defaultArg port 80
let endpoint = IPEndPoint(ipAddress, port)
let cts = new CancellationTokenSource()
let listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
listener.Bind(endpoint)
listener.Listen(int SocketOptionName.MaxConnections)
printfn "Started listening on port %d" port
let response = [|
"HTTP/1.1 200 OK\r\n"B
"Content-Type: text/plain\r\n"B
"\r\n"B
"Hello World!"B |] |> Array.concat
let rec loop() = async {
let! socket = listener.AsyncAccept()
// Setting ownsSocket to false allows us to later re-use a socket.
let stream = new NetworkStream(socket, false)
try
try
let! bytesSent = stream.AsyncWrite(response)
return ()
with e -> printfn "An error occurred: %s" e.Message
finally
stream.Close()
socket.Shutdown(SocketShutdown.Both)
socket.Close()
return! loop() }
Async.Start(loop(), cancellationToken = cts.Token)
{ new IDisposable with member x.Dispose() = cts.Cancel(); listener.Close() }
[<EntryPoint>]
let main argv =
let disposable = ServerM.Server.Start(port = 80)
Console.ReadKey() |> ignore
printfn "bye!"
disposable.Dispose()
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment