2011-09-23 55 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将剃一点点(如果它是供您选择的运输)。