对于实现 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<>() 函数的模板参数,并获得一个静态类型的对象作为返回值。
如果您有多种不同类型的 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);
}