F# sample
The following executable sample hosts an RPC server and client in the same process and connects them over a named pipe.
The IGreeter interface is the RPC contract shared by both sides.
namespace FSharpSample
open System
open System.IO.Pipes
open System.Threading.Tasks
open StreamJsonRpc
open Xunit
/// Defines the RPC contract shared by the client and server.
type IGreeter =
/// Returns a greeting for the specified name.
abstract GreetAsync: name: string -> Task<string>
/// Implements the RPC contract on the server.
type Greeter() =
interface IGreeter with
member _.GreetAsync(name) =
Task.FromResult($"Hello, {name}!")
module Program =
/// Verifies an RPC call between a client and server connected over a named pipe.
[<Fact>]
let ``Client receives a greeting from the server`` () =
task {
let pipeName = $"streamjsonrpc-fsharp-{Guid.NewGuid():N}"
use serverPipe =
new NamedPipeServerStream(
pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous
)
use clientPipe =
new NamedPipeClientStream(
".",
pipeName,
PipeDirection.InOut,
PipeOptions.Asynchronous
)
let serverConnection = serverPipe.WaitForConnectionAsync()
do! clientPipe.ConnectAsync()
do! serverConnection
use serverRpc = new JsonRpc(serverPipe)
serverRpc.AddLocalRpcTarget<IGreeter>(Greeter(), JsonRpcTargetOptions())
serverRpc.StartListening()
use clientRpc = new JsonRpc(clientPipe)
let server = clientRpc.Attach<IGreeter>()
clientRpc.StartListening()
let! greeting = server.GreetAsync("F#")
Assert.Equal("Hello, F#!", greeting)
}
Run the sample test from the repository root:
dotnet test --project samples/fs/FSharpSample.fsproj