-
-
Save panesofglass/2991544 to your computer and use it in GitHub Desktop.
Asynchronous socket programming with F# async.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System.Net.Sockets | |
type A = System.Net.Sockets.SocketAsyncEventArgs | |
type B = System.ArraySegment<byte> | |
exception SocketIssue of SocketError with | |
override this.ToString() = | |
string this.Data0 | |
/// Wraps the Socket.xxxAsync logic into F# async logic. | |
let inline asyncDo (op: A -> bool) (prepare: A -> unit) | |
(select: A -> 'T) = | |
Async.FromContinuations <| fun (ok, error, _) -> | |
let args = new A() | |
prepare args | |
let k (args: A) = | |
match args.SocketError with | |
| System.Net.Sockets.SocketError.Success -> | |
let result = select args | |
args.Dispose() | |
ok result | |
| e -> | |
args.Dispose() | |
error (SocketIssue e) | |
args.add_Completed(System.EventHandler<_>(fun _ -> k)) | |
if not (op args) then | |
k args | |
/// Prepares the arguments by setting the buffer. | |
let inline setBuffer (buf: B) (args: A) = | |
args.SetBuffer(buf.Array, buf.Offset, buf.Count) | |
let Accept (socket: Socket) = | |
asyncDo socket.AcceptAsync ignore (fun a -> a.AcceptSocket) | |
let Receive (socket: Socket) (buf: B) = | |
asyncDo socket.ReceiveAsync (setBuffer buf) | |
(fun a -> a.BytesTransferred) | |
let Send (socket: Socket) (buf: B) = | |
asyncDo socket.SendAsync (setBuffer buf) ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System.Net.Sockets | |
/// Thrown when sockets encounter errors. | |
exception SocketIssue of SocketError | |
/// Performs AcceptAsync. | |
val Accept : Socket -> Async<Socket> | |
/// Performs ReceiveAsync. | |
val Receive : Socket -> System.ArraySegment<byte> -> Async<int> | |
/// Performs SendAsync. | |
val Send : Socket -> System.ArraySegment<byte> -> Async<unit> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment