Связь между процессами с использованием WCF и F # - PullRequest
3 голосов
/ 23 сентября 2011

Я хотел бы сделать простую связь один к одному между двумя долго выполняющимися процессами 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 на самом деле использует это или нет?

Ответы [ 2 ]

4 голосов
/ 07 февраля 2013

Вам необходимо увеличить MaxReceivedMessageSize для привязки со значения по умолчанию 65536 как на клиенте, так и на сервере, чтобы вместить объем передаваемых данных.

Вы можете использовать Инспектор сообщений , чтобы проверить, действительно ли 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)
0 голосов
/ 23 сентября 2011

Я могу ответить только на «3»: используйте wireshark для проверки данных на проводе или иным образом рассчитайте время / измерьте полосу пропускания. Попробуйте с включенным протоколом protobunet и без него, и сравните. Сообщение protobuf будет содержать кусок двоичных данных вместо XML.

Примечание: если вы используете здесь protobuf-net, включение MTOM побьет чуть больше (если оно доступно для выбранного вами транспорта).

...