簡體   English   中英

使用WCF和F#的進程之間的通信

[英]Communication between processes using WCF and F#

我想使用F#在兩個長時間運行的F#進程之間進行簡單的一對一通信。 他們將每隔一段時間定期交換信息。 5秒。 到現在為止,我已達到這一點:

#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)

我得到了很多不同的例外,主要是由於不同的WCF安全限制。

我的問題是

  1. 我至少需要做些什么來使它工作?
  2. 我是否正確編寫了代碼以盡可能快地進行通信?
  3. 我試圖包括ProtoBuf序列化程序(參見代碼中的ProtoBehavior)以使序列化更快。 我是否正確實施了它? 我怎么知道WCF實際上是否使用它?

您需要在客戶端和服務器上從綁定的默認值65536增加綁定的MaxReceivedMessageSize屬性,以容納您正在傳輸的數據量。

您可以使用Message Inspector來檢查WCF是否實際使用ProtoBuf序列化程序(它不是)。 ProtoBehavior似乎僅應用於指定了DataContract / ProtoContract屬性的值。 因此,在下面的修改示例中,我創建了一個Vector記錄類型,也標記了F#3 CLIMutable屬性,以包裝數組:

#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)

我只能回答“3”:使用wireshark檢查線路上的數據,或以其他方式計時/測量帶寬。 嘗試使用/不啟用protobu-net,並進行比較。 protobuf消息將包含一大塊二進制數據而不是XML。

注意:如果您在這里使用protobuf-net,啟用MTOM會稍微多一點(如果它可用於您選擇的傳輸)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM