[+] TEngineServer

[+] TEngineServer
This commit is contained in:
ALEXTANG
2023-07-13 17:17:26 +08:00
parent a69f53592e
commit 0c8f3a5f92
790 changed files with 52737 additions and 2533 deletions

View File

@@ -0,0 +1,35 @@
#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace ProtoBuf.ServiceModel
{
/// <summary>
/// Uses protocol buffer serialization on the specified operation; note that this
/// must be enabled on both the client and server.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public sealed class ProtoBehaviorAttribute : Attribute, IOperationBehavior
{
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{ }
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription);
innerBehavior.ApplyClientBehavior(operationDescription, clientOperation);
}
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription);
innerBehavior.ApplyDispatchBehavior(operationDescription, dispatchOperation);
}
void IOperationBehavior.Validate(OperationDescription operationDescription)
{ }
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: feda16667cbcb8248951368dfbfef6b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER && FEAT_SERVICECONFIGMODEL
using System;
using System.ServiceModel.Configuration;
namespace ProtoBuf.ServiceModel
{
/// <summary>
/// Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint.
/// </summary>
/// <seealso cref="ProtoEndpointBehavior"/>
public class ProtoBehaviorExtension : BehaviorExtensionElement
{
/// <summary>
/// Creates a new ProtoBehaviorExtension instance.
/// </summary>
public ProtoBehaviorExtension() { }
/// <summary>
/// Gets the type of behavior.
/// </summary>
public override Type BehaviorType => typeof(ProtoEndpointBehavior);
/// <summary>
/// Creates a behavior extension based on the current configuration settings.
/// </summary>
/// <returns>The behavior extension.</returns>
protected override object CreateBehavior() => new ProtoEndpointBehavior();
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c70aaa3829dd1fa45b0530efc37727f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER
using System.ServiceModel.Description;
namespace ProtoBuf.ServiceModel
{
/// <summary>
/// Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint.
/// <example>
/// Add the following to the server and client app.config in the system.serviceModel section:
/// <behaviors>
/// <endpointBehaviors>
/// <behavior name="ProtoBufBehaviorConfig">
/// <ProtoBufSerialization/>
/// </behavior>
/// </endpointBehaviors>
/// </behaviors>
/// <extensions>
/// <behaviorExtensions>
/// <add name="ProtoBufSerialization" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=1.0.0.255, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
/// </behaviorExtensions>
/// </extensions>
///
/// Configure your endpoints to have a behaviorConfiguration as follows:
///
/// <service name="TK.Framework.Samples.ServiceModel.Contract.SampleService">
/// <endpoint address="http://myhost:9003/SampleService" binding="basicHttpBinding" behaviorConfiguration="ProtoBufBehaviorConfig"
/// bindingConfiguration="basicHttpBindingConfig" name="basicHttpProtoBuf" contract="ISampleServiceContract" />
/// </service>
/// <client>
/// <endpoint address="http://myhost:9003/SampleService" binding="basicHttpBinding"
/// bindingConfiguration="basicHttpBindingConfig" contract="ISampleServiceContract"
/// name="BasicHttpProtoBufEndpoint" behaviorConfiguration="ProtoBufBehaviorConfig"/>
/// </client>
/// </example>
/// </summary>
public class ProtoEndpointBehavior : IEndpointBehavior
{
#region IEndpointBehavior Members
void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{
ReplaceDataContractSerializerOperationBehavior(endpoint);
}
void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{
ReplaceDataContractSerializerOperationBehavior(endpoint);
}
void IEndpointBehavior.Validate(ServiceEndpoint endpoint)
{
}
private static void ReplaceDataContractSerializerOperationBehavior(ServiceEndpoint serviceEndpoint)
{
foreach (OperationDescription operationDescription in serviceEndpoint.Contract.Operations)
{
ReplaceDataContractSerializerOperationBehavior(operationDescription);
}
}
private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
description.Behaviors.Remove(dcsOperationBehavior);
ProtoOperationBehavior newBehavior = new ProtoOperationBehavior(description);
newBehavior.MaxItemsInObjectGraph = dcsOperationBehavior.MaxItemsInObjectGraph;
description.Behaviors.Add(newBehavior);
}
}
#endregion
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6776c4cee4f69a94e9507afa458fdb50
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel.Description;
using System.Xml;
using ProtoBuf.Meta;
namespace ProtoBuf.ServiceModel
{
/// <summary>
/// Describes a WCF operation behaviour that can perform protobuf serialization
/// </summary>
public sealed class ProtoOperationBehavior : DataContractSerializerOperationBehavior
{
private TypeModel model;
/// <summary>
/// Create a new ProtoOperationBehavior instance
/// </summary>
public ProtoOperationBehavior(OperationDescription operation) : base(operation)
{
#if !NO_RUNTIME
model = RuntimeTypeModel.Default;
#endif
}
/// <summary>
/// The type-model that should be used with this behaviour
/// </summary>
public TypeModel Model
{
get { return model; }
set
{
model = value ?? throw new ArgumentNullException(nameof(value));
}
}
//public ProtoOperationBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormat) : base(operation, dataContractFormat) { }
/// <summary>
/// Creates a protobuf serializer if possible (falling back to the default WCF serializer)
/// </summary>
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
{
if (model == null) throw new InvalidOperationException("No Model instance has been assigned to the ProtoOperationBehavior");
return XmlProtoSerializer.TryCreate(model, type) ?? base.CreateSerializer(type, name, ns, knownTypes);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bc6637ab509d5ba41b14e428ed365764
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,208 @@
#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
using ProtoBuf.Meta;
namespace ProtoBuf.ServiceModel
{
/// <summary>
/// An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[])
/// </summary>
public sealed class XmlProtoSerializer : XmlObjectSerializer
{
private readonly TypeModel model;
private readonly int key;
private readonly bool isList, isEnum;
private readonly Type type;
internal XmlProtoSerializer(TypeModel model, int key, Type type, bool isList)
{
if (key < 0) throw new ArgumentOutOfRangeException(nameof(key));
this.model = model ?? throw new ArgumentNullException(nameof(model));
this.key = key;
this.isList = isList;
this.type = type ?? throw new ArgumentOutOfRangeException(nameof(type));
this.isEnum = Helpers.IsEnum(type);
}
/// <summary>
/// Attempt to create a new serializer for the given model and type
/// </summary>
/// <returns>A new serializer instance if the type is recognised by the model; null otherwise</returns>
public static XmlProtoSerializer TryCreate(TypeModel model, Type type)
{
if (model == null) throw new ArgumentNullException(nameof(model));
if (type == null) throw new ArgumentNullException(nameof(type));
int key = GetKey(model, ref type, out bool isList);
if (key >= 0)
{
return new XmlProtoSerializer(model, key, type, isList);
}
return null;
}
/// <summary>
/// Creates a new serializer for the given model and type
/// </summary>
public XmlProtoSerializer(TypeModel model, Type type)
{
if (model == null) throw new ArgumentNullException(nameof(model));
if (type == null) throw new ArgumentNullException(nameof(type));
key = GetKey(model, ref type, out isList);
this.model = model;
this.type = type;
this.isEnum = Helpers.IsEnum(type);
if (key < 0) throw new ArgumentOutOfRangeException(nameof(type), "Type not recognised by the model: " + type.FullName);
}
static int GetKey(TypeModel model, ref Type type, out bool isList)
{
if (model != null && type != null)
{
int key = model.GetKey(ref type);
if (key >= 0)
{
isList = false;
return key;
}
Type itemType = TypeModel.GetListItemType(model, type);
if (itemType != null)
{
key = model.GetKey(ref itemType);
if (key >= 0)
{
isList = true;
return key;
}
}
}
isList = false;
return -1;
}
/// <summary>
/// Ends an object in the output
/// </summary>
public override void WriteEndObject(XmlDictionaryWriter writer)
{
if (writer == null) throw new ArgumentNullException(nameof(writer));
writer.WriteEndElement();
}
/// <summary>
/// Begins an object in the output
/// </summary>
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
{
if (writer == null) throw new ArgumentNullException(nameof(writer));
writer.WriteStartElement(PROTO_ELEMENT);
}
private const string PROTO_ELEMENT = "proto";
/// <summary>
/// Writes the body of an object in the output
/// </summary>
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
{
if (writer == null) throw new ArgumentNullException(nameof(writer));
if (graph == null)
{
writer.WriteAttributeString("nil", "true");
}
else
{
using (MemoryStream ms = new MemoryStream())
{
if (isList)
{
model.Serialize(ms, graph, null);
}
else
{
using (ProtoWriter protoWriter = ProtoWriter.Create(ms, model, null))
{
model.Serialize(key, graph, protoWriter);
}
}
byte[] buffer = ms.GetBuffer();
writer.WriteBase64(buffer, 0, (int)ms.Length);
}
}
}
/// <summary>
/// Indicates whether this is the start of an object we are prepared to handle
/// </summary>
public override bool IsStartObject(XmlDictionaryReader reader)
{
if (reader == null) throw new ArgumentNullException(nameof(reader));
reader.MoveToContent();
return reader.NodeType == XmlNodeType.Element && reader.Name == PROTO_ELEMENT;
}
/// <summary>
/// Reads the body of an object
/// </summary>
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{
if (reader == null) throw new ArgumentNullException(nameof(reader));
reader.MoveToContent();
bool isSelfClosed = reader.IsEmptyElement, isNil = reader.GetAttribute("nil") == "true";
reader.ReadStartElement(PROTO_ELEMENT);
// explicitly null
if (isNil)
{
if (!isSelfClosed) reader.ReadEndElement();
return null;
}
if (isSelfClosed) // no real content
{
if (isList || isEnum)
{
return model.Deserialize(Stream.Null, null, type, null);
}
ProtoReader protoReader = null;
try
{
protoReader = ProtoReader.Create(Stream.Null, model, null, ProtoReader.TO_EOF);
return model.Deserialize(key, null, protoReader);
}
finally
{
ProtoReader.Recycle(protoReader);
}
}
object result;
Helpers.DebugAssert(reader.CanReadBinaryContent, "CanReadBinaryContent");
using (MemoryStream ms = new MemoryStream(reader.ReadContentAsBase64()))
{
if (isList || isEnum)
{
result = model.Deserialize(ms, null, type, null);
}
else
{
ProtoReader protoReader = null;
try
{
protoReader = ProtoReader.Create(ms, model, null, ProtoReader.TO_EOF);
result = model.Deserialize(key, null, protoReader);
}
finally
{
ProtoReader.Recycle(protoReader);
}
}
}
reader.ReadEndElement();
return result;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bca9bc75e9bb7c841b04b85204a0c9f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: