简体   繁体   中英

Communication between processes using WCF and F#

I would like to make a simple one to one communication between two long time running F# processes using F#. They will exchange information regularly every ca. 5 seconds. Until now, I have reached this point:

#r "System.ServiceModel"
#r "System.Runtime.Serialization"
//#r @"d:\DLL\Protobuf\protobuf-net.dll"
#time "on"

open System.ServiceModel

[<ServiceContract>]
type IService =
  [<OperationContract>]
  // [<ProtoBuf.ServiceModel.ProtoBehavior>]
  abstract Test: float [] [] [] -> string

type Service () =
  interface IService with
    member o.Test data = sprintf "Hello, %A" data

let server = System.Threading.Thread (fun () ->
  let svh = new ServiceHost (typeof<Service>)
  svh.AddServiceEndpoint (typeof<IService>, NetNamedPipeBinding(), "net.pipe://localhost/123") |> ignore
  svh.Open () )

server.IsBackground <- true
server.Start()

let scf: IService = ChannelFactory.CreateChannel (NetNamedPipeBinding(), EndpointAddress "net.pipe://localhost/123")
let rnd = System.Random ()
let arr =
  Array.init 100 (fun i ->
    Array.init 10 (fun j ->
      Array.init 10 (fun k ->
        rnd.NextDouble()
  )))

printfn "%s" (scf.Test arr)

I get a plenty of different exceptions mainly due to different WCF security limits.

My questions are

  1. What do I need to do at minimum to make it work?
  2. Did I write the code correctly to make the communication as fast as possible?
  3. I have tried to include ProtoBuf serializer (see ProtoBehavior in the code) to make the serialization even faster. Did I implemented it correctly? How do I know that WCF actually uses it or not?

You need to increase MaxReceivedMessageSize property on the binding from it's default value of 65536 on both the client and server to accommodate the volume of data you are transferring.

You can use a Message Inspector to check if WCF is actually using the ProtoBuf serializer (which it isn't). The ProtoBehavior appears to only be applied to values with a DataContract/ProtoContract attribute specified. So in the modified example below I have created a Vector record type, also marked with the F# 3 CLIMutable attribute, to wrap the arrays:

#r "System.ServiceModel"
#r "System.Runtime.Serialization"
#r "protobuf-net.dll"
#time "on"

open System.ServiceModel
open System.Runtime.Serialization

[<DataContract; ProtoBuf.ProtoContract; CLIMutable>]
type Vector<'T> = { [<DataMember; ProtoBuf.ProtoMember(1)>] Values : 'T[] }

[<ServiceContract>]
type IService =
  [<OperationContract>]
  [<ProtoBuf.ServiceModel.ProtoBehavior>]
  abstract Test: Vector<Vector<Vector<float>>> -> string

type Service () =
  interface IService with
    member o.Test data = sprintf "Hello, %A" data

let server = System.Threading.Thread (fun () ->
  let svh = new ServiceHost (typeof<Service>)
  let binding = NetNamedPipeBinding()
  binding.MaxReceivedMessageSize <- binding.MaxReceivedMessageSize * 4L
  svh.AddServiceEndpoint (typeof<IService>, binding, "net.pipe://localhost/123") |> ignore
  svh.Open () )

server.IsBackground <- true
server.Start()

let scf: IService = 
   let binding = NetNamedPipeBinding()
   binding.MaxReceivedMessageSize <- binding.MaxReceivedMessageSize * 4L
   ChannelFactory.CreateChannel (binding, EndpointAddress "net.pipe://localhost/123")
let rnd = System.Random ()
let arr =
  { Values = Array.init 100 (fun i ->
   { Values =
      Array.init 10 (fun j ->
         { Values =Array.init 10 (fun k -> rnd.NextDouble()) }
      )}
   )}

printfn "%s" (scf.Test arr)

I can only answer "3" : use wireshark to inspect the data on the wire, or otherwise time it / measure re bandwidth. Try it with/without protobu-net enabled, and compare. A protobuf message will have a chunk of binary data instead of XML.

Note: if you are using protobuf-net here, enabling MTOM will shave a little bit more (if it is available for your chosen transport).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM