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

时间:2015-01-26 18:27:28

标签: c# android json wcf websocket

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

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

对于实现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对象的类型 - 为每个对象创建一个corrseponding C#类!这样,您可以使用该类作为Deserialize<>()函数的模板参数,并获取静态类型的对象作为返回值。

如果您有多种不同类型的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);
}