Skip to content

Commit

Permalink
Updated scripts for Expert F# 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
granicz committed Jan 28, 2016
1 parent 05a7e56 commit 7fa3b71
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 130 deletions.
91 changes: 41 additions & 50 deletions 14Web/AsyncTcpServer.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,53 @@ open System.Text

type AsyncTcpServer(addr, port, handleServerRequest) =
let socket = new TcpListener(addr, port)
member x.Start() = async {do x.Run()} |> Async.Start

member x.Start() = async { do x.Run() } |> Async.Start

member x.Run() =
socket.Start()
while true do
let client = socket.AcceptTcpClient()
async {try do! handleServerRequest client with e -> ()}
async {
try do! handleServerRequest client with e -> ()
}
|> Async.Start

let quoteSize = 8
let quoteHeaderSize = 4
let quoteSeriesLength = 3
let header = Array.init<byte> quoteSize (fun i -> 1uy)
let quote = Array.init<byte> quoteSize (fun i -> byte(i % 256))
module Quotes =
let private quoteSize = 8
let private quoteHeaderSize = 4
let private quoteSeriesLength = 3

let handleRequest (client : TcpClient) = async {
use stream = client.GetStream()
do! stream.AsyncWrite(header, 0, quoteHeaderSize) // write header
for _ in [0 .. quoteSeriesLength] do
do! stream.AsyncWrite(quote, 0, quote.Length)
// Mock an I/O wait for the next quote
do! Async.Sleep 1000}
module Server =
let HandleRequest (client: TcpClient) =
// Dummy header and quote
let header = Array.init<byte> quoteSize (fun i -> 1uy)
let quote = Array.init<byte> quoteSize (fun i -> byte(i % 256))
async {
use stream = client.GetStream()
do! stream.AsyncWrite(header, 0, quoteHeaderSize) // Header
for _ in [0 .. quoteSeriesLength] do
do! stream.AsyncWrite(quote, 0, quote.Length)
// Mock an I/O wait for the next quote
do! Async.Sleep 1000
}

let server = new AsyncTcpServer(IPAddress.Loopback, 10003, handleRequest)
let Start () =
let S = new AsyncTcpServer(IPAddress.Loopback,10003,HandleRequest)
S.Start()

let printQuotes = async {
let client = new TcpClient()
client.Connect(IPAddress.Loopback, 10003)
use stream = client.GetStream()
let header = Array.create quoteHeaderSize 0uy
let! readHeader = stream.AsyncRead(header, 0, quoteHeaderSize)
if readHeader = 0 then return () else printfn "Header: %A" header
while true do
let buffer = Array.create quoteSize 0uy
let! read = stream.AsyncRead(buffer, 0, quoteSize)
if read = 0 then return () else printfn "Quote: %A" buffer}
//type AsyncTcpServer =
// class
// new : addr:System.Net.IPAddress * port:int *
// handleServerRequest:(System.Net.Sockets.TcpClient -> Async<unit>) ->
// AsyncTcpServer
// member Run : unit -> unit
// member Start : unit -> unit
// end
//val quoteSize : int = 8
//val quoteHeaderSize : int = 4
//val quoteSeriesLength : int = 3
//val header : byte [] = [|1uy; 1uy; 1uy; 1uy; 1uy; 1uy; 1uy; 1uy|]
//val quote : byte [] = [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
//val handleRequest : client:System.Net.Sockets.TcpClient -> Async<unit>
//val server : AsyncTcpServer
//val printQuotes : Async<unit>

server.Start()
Async.Start printQuotes
//Header: [|1uy; 1uy; 1uy; 1uy|]
//Quote: [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
//Quote: [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
//Quote: [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
//Quote: [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
module Client =
let RequestQuote =
async {
let client = new TcpClient()
client.Connect(IPAddress.Loopback, 10003)
use stream = client.GetStream()
let header = Array.create quoteHeaderSize 0uy
let! read = stream.AsyncRead(header, 0, quoteHeaderSize)
if read = 0 then return () else printfn "Header: %A" header
while true do
let buffer = Array.create quoteSize 0uy
let! read = stream.AsyncRead(buffer, 0, quoteSize)
if read = 0 then return () else printfn "Quote: %A" buffer
}
|> Async.Start
88 changes: 15 additions & 73 deletions 14Web/AsyncTcpServerSecure.fsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,26 @@
open System.Net
open System.Net.Sockets
open System.IO
open System.Text
open System.Security.Cryptography.X509Certificates
open System.Net.Security
open System.Security.Authentication
open System.Security.Cryptography.X509Certificates

type AsyncTcpServer(addr, port, handleServerRequest) =
let socket = new TcpListener(addr, port)
member x.Start() = async {do x.Run()} |> Async.Start

member x.Start() = async { do x.Run() } |> Async.Start

member x.Run() =
socket.Start()
while true do
let client = socket.AcceptTcpClient()
async {try do! handleServerRequest client with e -> ()}
async {
try do! handleServerRequest (client.GetStream()) with e -> ()
}
|> Async.Start

let quoteSize = 8
let quoteHeaderSize = 4
let quoteSeriesLength = 3
let header = Array.init<byte> quoteSize (fun i -> 1uy)
let quote = Array.init<byte> quoteSize (fun i -> byte(i % 256))

let handleRequestStream (stream : Stream) = async {
do! stream.AsyncWrite(header, 0, quoteHeaderSize) // write header
for _ in [0 .. quoteSeriesLength] do
do! stream.AsyncWrite(quote, 0, quote.Length)
// Mock an I/O wait for the next quote
do! Async.Sleep 1000}

let handleRequest (client : TcpClient) = async {
use stream = client.GetStream()
do! handleRequestStream stream}

type AsyncTcpServerSecure(addr, port, handleServerRequest) =

/// Gets the first self-signed certificate with a friendly name of localhost.
// Gets the first certificate with a friendly name of localhost.
let getCertficate() =
let store = new X509Store(StoreName.My, StoreLocation.LocalMachine)
store.Open(OpenFlags.ReadOnly)
Expand All @@ -44,15 +29,15 @@ type AsyncTcpServerSecure(addr, port, handleServerRequest) =
findType = X509FindType.FindBySubjectName,
findValue = Dns.GetHostName(),
validOnly = true)
certs
|> Seq.cast<X509Certificate2>
|> Seq.tryFind (fun c -> c.FriendlyName = "localhost")
seq {
for c in certs do if c.FriendlyName = "localhost" then yield Some(c)
yield None}
|> Seq.head

let handleServerRequestSecure (client : TcpClient) =
let handleServerRequestSecure (stream: NetworkStream) =
async {
let cert = getCertficate()
if cert.IsNone then printfn "No cert"; return ()
let stream = client.GetStream()
let sslStream = new SslStream(innerStream = stream, leaveInnerStreamOpen = true)
try
sslStream.AuthenticateAsServer(
Expand All @@ -72,52 +57,9 @@ type AsyncTcpServerSecure(addr, port, handleServerRequest) =
// is authenticated as a server.
printfn "IsServer: %A" sslStream.IsServer

return! handleRequestStream stream
return! handleServerRequest stream
}

let server = AsyncTcpServer(addr, port, handleServerRequestSecure)
let server = AsyncTcpServerSecure(addr, port, handleServerRequestSecure)

member x.Start() = server.Start()

let server = new AsyncTcpServerSecure(IPAddress.Loopback, 10003, handleRequest)

let printQuotes = async {
let client = new TcpClient()
client.Connect(IPAddress.Loopback, 10003)
use stream = client.GetStream()
let header = Array.create quoteHeaderSize 0uy
let! readHeader = stream.AsyncRead(header, 0, quoteHeaderSize)
if readHeader = 0 then return () else printfn "Header: %A" header
while true do
let buffer = Array.create quoteSize 0uy
let! read = stream.AsyncRead(buffer, 0, quoteSize)
if read = 0 then return () else printfn "Quote: %A" buffer}
//type AsyncTcpServer =
// class
// new : addr:System.Net.IPAddress * port:int *
// handleServerRequest:(System.Net.Sockets.TcpClient -> Async<unit>) ->
// AsyncTcpServer
// member Run : unit -> unit
// member Start : unit -> unit
// end
//val quoteSize : int = 8
//val quoteHeaderSize : int = 4
//val quoteSeriesLength : int = 3
//val header : byte [] = [|1uy; 1uy; 1uy; 1uy; 1uy; 1uy; 1uy; 1uy|]
//val quote : byte [] = [|0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy|]
//val handleRequestStream : stream:System.IO.Stream -> Async<unit>
//val handleRequest : client:System.Net.Sockets.TcpClient -> Async<unit>
//type AsyncTcpServerSecure =
// class
// new : addr:System.Net.IPAddress * port:int *
// handleServerRequest:(System.Net.Sockets.TcpClient -> Async<unit>) ->
// AsyncTcpServerSecure
// member Start : unit -> unit
// end
//val server : AsyncTcpServerSecure
//val printQuotes : Async<unit>

// On Windows 7, to create a self-signed certificate, open IIS7, server certificates
// and choose the action create self-signed certificate.
server.Start()
Async.Start printQuotes
8 changes: 1 addition & 7 deletions 14Web/WebServer.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ let server = async {
while true do
use client = socket.AcceptTcpClient()
do! handleRequest client}
//val mimeTypes : System.Collections.Generic.IDictionary<string,string>
//val getMimeType : ext:string -> string
//val ( |Regex1|_| ) : patt:string -> inp:string -> string option
//val root : string = "c:\inetpub\wwwroot"
//val handleRequest : client:System.Net.Sockets.TcpClient -> Async<unit>
//val server : Async<unit>

> Async.Start server;;
//Async.Start server;;
//val it : unit = ()

0 comments on commit 7fa3b71

Please sign in to comment.