我想使用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安全限制。
我的问题是
答案 0 :(得分:4)
您需要在客户端和服务器上从绑定的默认值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)
答案 1 :(得分:0)
我只能回答“3”:使用wireshark检查线路上的数据,或以其他方式计时/测量带宽。尝试使用/不启用protobu-net,并进行比较。 protobuf消息将包含一大块二进制数据而不是XML。
注意:如果您在这里使用protobuf-net,启用MTOM会稍微多一点(如果它适用于您选择的传输)。