2011-09-23 7 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 serializer (코드에서 ProtoBehavior 참조)를 포함시켜 직렬화를 더욱 빠르게 만들려고했습니다. 올바르게 구현 했습니까? WCF가 실제로 사용하는지 여부를 어떻게 알 수 있습니까?

답변

4

전송중인 데이터의 양을 수용하기 위해 클라이언트와 서버 모두에서 바인딩의 기본값 인 65536에서 바인딩의 MaxReceivedMessageSize 속성을 늘려야합니다.

Message Inspector을 사용하여 WCF가 실제로 ProtoBuf serializer를 사용하고 있는지 확인할 수 있습니다 (그렇지 않은 경우). 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 대신 2 진 데이터가 있습니다.

참고 : 여기에서 protobuf-net을 사용하는 경우 MTOM을 사용하도록 설정하면 선택한 전송에 사용할 수있는 경우 조금 더 줄일 수 있습니다.