WCF - 使用 NetHttpBinding(WebSockets) 或替代双工绑定发送 JSON

Posted

技术标签:

【中文标题】WCF - 使用 NetHttpBinding(WebSockets) 或替代双工绑定发送 JSON【英文标题】:WCF - Sending JSON with NetHttpBinding(WebSockets) or alternative Duplex Binding 【发布时间】:2015-03-25 05:37:49 【问题描述】:

我正在尝试将 android 客户端连接到当前使用 NetTcpBinding 运行的 WCF 服务。该项目要求所有客户端都具有双工(双向)连接。

由于 .NET 之外不支持 NetTcpBinding,我开始研究替代的双工绑定。 Websockets(NetHttpBinding) 似乎是答案,但它似乎没有内置对 JSON 的支持,并且应用相同的 WebHttpBinding 绑定配置会引发错误。

非常感谢任何有关将使用 JSON 的 Andriod 客户端添加到双工 WCF 服务的建议。

【问题讨论】:

【参考方案1】:

对此的一个简单解决方案是使用 Newtonsoft 将 WCF 返回对象转换为 JSON 字符串,并在客户端使用 JSON.stringyfy 或 android 中的类似函数解析此字符串。

【讨论】:

【参考方案2】:

对于实现 WebSockects 的 WCF WebService,您可以像这样定义自定义绑定:

<customBinding>
  <binding name="WebSocketBinding">
    <byteStreamMessageEncoding />
    <httpTransport>
      <webSocketSettings transportUsage="Always" />
    </httpTransport>
  </binding>
</customBinding>

您的服务接口必须如下所示:

[ServiceContract(CallbackContract = typeof(IMyCallBack))]
public interface IMyService

    [OperationContract(IsOneWay = true, Action = "*")]
    void OnMessage(System.ServiceModel.Channels.Message msg);

[ServiceContract]
interface IMyCallBack

    [OperationContract(IsOneWay = true, Action="*")]
    void Reply(System.ServiceModel.Channels.Message msg);

服务实现:

public class MyService: IMyService

    public void OnMessage(Message msg)
    
        var callback = OperationContext.Current.GetCallbackChannel<IMyCallback>();
        if (msg.IsEmpty || ((IChannel)callback).State != CommunicationState.Opened)
        
            return;
        
        byte[] messageBody = msg.GetBody<byte[]>();
        string messageString = Encoding.UTF8.GetString(messageBody);

        ...

        callback.Reply(CreateMessage(responseString));
    

    private Message CreateMessage(string messageString)
    
        var messageBody = new ArraySegment<byte>(Encoding.UTF8.GetBytes(messageString));
        Message msg = ByteStreamMessage.CreateMessage(messageBody);
        msg.Properties["WebSocketMessageProperty"] = new WebSocketMessageProperty 
         
            MessageType = WebSocketMessageType.Text 
        ;
        return msg;
    
 

这样,您的服务可以从您的客户端接收字符串化的 JSON 对象。该服务将以System.ServiceModel.Channels.ByteStreamMessage 对象的形式接收它们,这些对象本质上包含纯字符串,从而使转换非常简单,如上所示。

要将服务上的字符串化 JSON 对象转换为您可以实际使用的对象,您可以使用序列化程序:

var serializer = new System.Web.Script.Serialization.javascriptSerializer();
dynamic messageObject = serializer.Deserialize<object>(stringMessage);

更好的选择是使用静态类型:我假设您知道要传输的 JSON 对象的类型 - 为每个对象创建一个对应的 C# 类!这样,您就可以将类用作Deserialize&lt;&gt;() 函数的模板参数,并获得一个静态类型的对象作为返回值。

如果您有多种不同类型的 JSON 对象,您可以为它们添加 type 属性,然后您可以在服务端对其进行排序:

dynamic messageObject = serializer.Deserialize<object>(stringMessage);

if (messageObject["type"] == "MyObject1") 
    MyObject1 myObject = serializer.Deserialize<MyObject1>(stringMessage);
    MyFunction1(myObject);
 else if (messageObject["type"] == "MyObject2") 
    MyObject2 myObject = serializer.Deserialize<MyObject2>(stringMessage);
    MyFunction2(myObject);

【讨论】:

以上是关于WCF - 使用 NetHttpBinding(WebSockets) 或替代双工绑定发送 JSON的主要内容,如果未能解决你的问题,请参考以下文章

通过 DI 的 WCF 构造函数服务类型

使用 net tcp 的 WCF 双工服务:“需要流安全性...”

WCF ChannelFactory 和通道 - 缓存、重用、关闭和恢复

一什么是WCF

如何为具有共享类型的多个 WCF 服务生成客户端代码

WCF RESTFul服务中的异常处理