2011-09-23 37 views
3

進程之間的通信,我想作一個簡單的一對一通信兩個長的時間之間運行使用F#F#的過程。他們會定期交換信息。 5秒。到目前爲止,我已經達到了這一點:使用WCF和F#

#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實際使用它?

回答

4

你需要增加MaxReceivedMessageSize財產上的約束力,從它的客戶端和服務器上的65536默認值,以適應數據的要傳輸的卷。

您可以使用Message Inspector如果WCF實際上是使用protobuf的串行檢查(它不是)。 ProtoBehavior似乎只適用於指定了DataContract/ProtoContract屬性的值。因此,在變形例下面我已經創建了一個向量記錄類型,還標有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) 
+0

尼斯一個哥們!!! – Nikos

0

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

注:如果您在此處使用protobuf網,使MTOM將剃一點點(如果它是供您選擇的運輸)。