mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-07 10:48:51 +00:00
THRIFT-4535: XML docs; code cleanup (tabs->spaces; String->string)
Client: C# Patch: Christian Weiss This closes #1524
This commit is contained in:
parent
d4fb364d30
commit
8fb719efb1
@ -79,7 +79,7 @@ namespace Thrift.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
int hashcode = 0;
|
int hashcode = 0;
|
||||||
foreach (Object obj in enumerable)
|
foreach (object obj in enumerable)
|
||||||
{
|
{
|
||||||
IEnumerable enum2 = obj as IEnumerable;
|
IEnumerable enum2 = obj as IEnumerable;
|
||||||
int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
|
int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
|
||||||
@ -91,4 +91,4 @@ namespace Thrift.Collections
|
|||||||
return hashcode;
|
return hashcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ namespace Thrift.Protocol
|
|||||||
{
|
{
|
||||||
public interface TAbstractBase
|
public interface TAbstractBase
|
||||||
{
|
{
|
||||||
///
|
/// <summary>
|
||||||
/// Writes the objects out to the protocol
|
/// Writes the objects out to the protocol.
|
||||||
///
|
/// </summary>
|
||||||
void Write(TProtocol tProtocol);
|
void Write(TProtocol tProtocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ namespace Thrift.Protocol
|
|||||||
{
|
{
|
||||||
public interface TBase : TAbstractBase
|
public interface TBase : TAbstractBase
|
||||||
{
|
{
|
||||||
///
|
/// <summary>
|
||||||
/// Reads the TObject from the given input protocol.
|
/// Reads the TObject from the given input protocol.
|
||||||
///
|
/// </summary>
|
||||||
void Read(TProtocol tProtocol);
|
void Read(TProtocol tProtocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,29 +36,28 @@ namespace Thrift.Protocol
|
|||||||
protected bool strictWrite_ = true;
|
protected bool strictWrite_ = true;
|
||||||
|
|
||||||
#region BinaryProtocol Factory
|
#region BinaryProtocol Factory
|
||||||
/**
|
|
||||||
* Factory
|
|
||||||
*/
|
|
||||||
public class Factory : TProtocolFactory {
|
|
||||||
|
|
||||||
protected bool strictRead_ = false;
|
public class Factory : TProtocolFactory
|
||||||
protected bool strictWrite_ = true;
|
{
|
||||||
|
protected bool strictRead_ = false;
|
||||||
|
protected bool strictWrite_ = true;
|
||||||
|
|
||||||
public Factory()
|
public Factory()
|
||||||
:this(false, true)
|
: this(false, true)
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
public Factory(bool strictRead, bool strictWrite)
|
|
||||||
{
|
|
||||||
strictRead_ = strictRead;
|
|
||||||
strictWrite_ = strictWrite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TProtocol GetProtocol(TTransport trans) {
|
|
||||||
return new TBinaryProtocol(trans, strictRead_, strictWrite_);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public Factory(bool strictRead, bool strictWrite)
|
||||||
|
{
|
||||||
|
strictRead_ = strictRead;
|
||||||
|
strictWrite_ = strictWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TProtocol GetProtocol(TTransport trans)
|
||||||
|
{
|
||||||
|
return new TBinaryProtocol(trans, strictRead_, strictWrite_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
|
public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
|
||||||
:base(trans)
|
: base(trans)
|
||||||
{
|
{
|
||||||
strictRead_ = strictRead;
|
strictRead_ = strictRead;
|
||||||
strictWrite_ = strictWrite;
|
strictWrite_ = strictWrite;
|
||||||
@ -345,16 +344,17 @@ namespace Thrift.Protocol
|
|||||||
public override long ReadI64()
|
public override long ReadI64()
|
||||||
{
|
{
|
||||||
ReadAll(i64in, 0, 8);
|
ReadAll(i64in, 0, 8);
|
||||||
unchecked {
|
unchecked
|
||||||
return (long)(
|
{
|
||||||
((long)(i64in[0] & 0xff) << 56) |
|
return (long)(
|
||||||
((long)(i64in[1] & 0xff) << 48) |
|
((long)(i64in[0] & 0xff) << 56) |
|
||||||
((long)(i64in[2] & 0xff) << 40) |
|
((long)(i64in[1] & 0xff) << 48) |
|
||||||
((long)(i64in[3] & 0xff) << 32) |
|
((long)(i64in[2] & 0xff) << 40) |
|
||||||
((long)(i64in[4] & 0xff) << 24) |
|
((long)(i64in[3] & 0xff) << 32) |
|
||||||
((long)(i64in[5] & 0xff) << 16) |
|
((long)(i64in[4] & 0xff) << 24) |
|
||||||
((long)(i64in[6] & 0xff) << 8) |
|
((long)(i64in[5] & 0xff) << 16) |
|
||||||
((long)(i64in[7] & 0xff)));
|
((long)(i64in[6] & 0xff) << 8) |
|
||||||
|
((long)(i64in[7] & 0xff)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +378,7 @@ namespace Thrift.Protocol
|
|||||||
trans.ReadAll(buf, 0, size);
|
trans.ReadAll(buf, 0, size);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
private string ReadStringBody(int size)
|
private string ReadStringBody(int size)
|
||||||
{
|
{
|
||||||
byte[] buf = new byte[size];
|
byte[] buf = new byte[size];
|
||||||
trans.ReadAll(buf, 0, size);
|
trans.ReadAll(buf, 0, size);
|
||||||
|
@ -44,9 +44,9 @@ namespace Thrift.Protocol
|
|||||||
private const byte TYPE_BITS = 0x07; // 0000 0111
|
private const byte TYPE_BITS = 0x07; // 0000 0111
|
||||||
private const int TYPE_SHIFT_AMOUNT = 5;
|
private const int TYPE_SHIFT_AMOUNT = 5;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* All of the on-wire type codes.
|
/// All of the on-wire type codes.
|
||||||
*/
|
/// </summary>
|
||||||
private static class Types
|
private static class Types
|
||||||
{
|
{
|
||||||
public const byte STOP = 0x00;
|
public const byte STOP = 0x00;
|
||||||
@ -64,32 +64,29 @@ namespace Thrift.Protocol
|
|||||||
public const byte STRUCT = 0x0C;
|
public const byte STRUCT = 0x0C;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Used to keep track of the last field for the current and previous structs,
|
/// Used to keep track of the last field for the current and previous structs,
|
||||||
* so we can do the delta stuff.
|
/// so we can do the delta stuff.
|
||||||
*/
|
/// </summary>
|
||||||
private Stack<short> lastField_ = new Stack<short>(15);
|
private Stack<short> lastField_ = new Stack<short>(15);
|
||||||
|
|
||||||
private short lastFieldId_ = 0;
|
private short lastFieldId_ = 0;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* If we encounter a boolean field begin, save the TField here so it can
|
/// If we encounter a boolean field begin, save the TField here so it can
|
||||||
* have the value incorporated.
|
/// have the value incorporated.
|
||||||
*/
|
/// </summary>
|
||||||
private Nullable<TField> booleanField_;
|
private Nullable<TField> booleanField_;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* If we Read a field header, and it's a boolean field, save the boolean
|
/// If we Read a field header, and it's a boolean field, save the boolean
|
||||||
* value here so that ReadBool can use it.
|
/// value here so that ReadBool can use it.
|
||||||
*/
|
/// </summary>
|
||||||
private Nullable<Boolean> boolValue_;
|
private Nullable<Boolean> boolValue_;
|
||||||
|
|
||||||
|
|
||||||
#region CompactProtocol Factory
|
#region CompactProtocol Factory
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory
|
|
||||||
*/
|
|
||||||
public class Factory : TProtocolFactory
|
public class Factory : TProtocolFactory
|
||||||
{
|
{
|
||||||
public Factory() { }
|
public Factory() { }
|
||||||
@ -127,31 +124,32 @@ namespace Thrift.Protocol
|
|||||||
|
|
||||||
#region Write Methods
|
#region Write Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
/**
|
/// Writes a byte without any possibility of all that field header nonsense.
|
||||||
* Writes a byte without any possibility of all that field header nonsense.
|
/// Used internally by other writing methods that know they need to Write a byte.
|
||||||
* Used internally by other writing methods that know they need to Write a byte.
|
/// </summary>
|
||||||
*/
|
|
||||||
private byte[] byteDirectBuffer = new byte[1];
|
private byte[] byteDirectBuffer = new byte[1];
|
||||||
|
|
||||||
private void WriteByteDirect(byte b)
|
private void WriteByteDirect(byte b)
|
||||||
{
|
{
|
||||||
byteDirectBuffer[0] = b;
|
byteDirectBuffer[0] = b;
|
||||||
trans.Write(byteDirectBuffer);
|
trans.Write(byteDirectBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Writes a byte without any possibility of all that field header nonsense.
|
/// Writes a byte without any possibility of all that field header nonsense.
|
||||||
*/
|
/// </summary>
|
||||||
private void WriteByteDirect(int n)
|
private void WriteByteDirect(int n)
|
||||||
{
|
{
|
||||||
WriteByteDirect((byte)n);
|
WriteByteDirect((byte)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write an i32 as a varint. Results in 1-5 bytes on the wire.
|
/// Write an i32 as a varint. Results in 1-5 bytes on the wire.
|
||||||
* TODO: make a permanent buffer like WriteVarint64?
|
/// TODO: make a permanent buffer like WriteVarint64?
|
||||||
*/
|
/// </summary>
|
||||||
byte[] i32buf = new byte[5];
|
byte[] i32buf = new byte[5];
|
||||||
|
|
||||||
private void WriteVarint32(uint n)
|
private void WriteVarint32(uint n)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -174,10 +172,10 @@ namespace Thrift.Protocol
|
|||||||
trans.Write(i32buf, 0, idx);
|
trans.Write(i32buf, 0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a message header to the wire. Compact Protocol messages contain the
|
/// Write a message header to the wire. Compact Protocol messages contain the
|
||||||
* protocol version so we can migrate forwards in the future if need be.
|
/// protocol version so we can migrate forwards in the future if need be.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteMessageBegin(TMessage message)
|
public override void WriteMessageBegin(TMessage message)
|
||||||
{
|
{
|
||||||
WriteByteDirect(PROTOCOL_ID);
|
WriteByteDirect(PROTOCOL_ID);
|
||||||
@ -186,33 +184,33 @@ namespace Thrift.Protocol
|
|||||||
WriteString(message.Name);
|
WriteString(message.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a struct begin. This doesn't actually put anything on the wire. We
|
/// Write a struct begin. This doesn't actually put anything on the wire. We
|
||||||
* use it as an opportunity to put special placeholder markers on the field
|
/// use it as an opportunity to put special placeholder markers on the field
|
||||||
* stack so we can get the field id deltas correct.
|
/// stack so we can get the field id deltas correct.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteStructBegin(TStruct strct)
|
public override void WriteStructBegin(TStruct strct)
|
||||||
{
|
{
|
||||||
lastField_.Push(lastFieldId_);
|
lastField_.Push(lastFieldId_);
|
||||||
lastFieldId_ = 0;
|
lastFieldId_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a struct end. This doesn't actually put anything on the wire. We use
|
/// Write a struct end. This doesn't actually put anything on the wire. We use
|
||||||
* this as an opportunity to pop the last field from the current struct off
|
/// this as an opportunity to pop the last field from the current struct off
|
||||||
* of the field stack.
|
/// of the field stack.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteStructEnd()
|
public override void WriteStructEnd()
|
||||||
{
|
{
|
||||||
lastFieldId_ = lastField_.Pop();
|
lastFieldId_ = lastField_.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a field header containing the field id and field type. If the
|
/// Write a field header containing the field id and field type. If the
|
||||||
* difference between the current field id and the last one is small (< 15),
|
/// difference between the current field id and the last one is small (< 15),
|
||||||
* then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
|
/// then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
|
||||||
* field id will follow the type header as a zigzag varint.
|
/// field id will follow the type header as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteFieldBegin(TField field)
|
public override void WriteFieldBegin(TField field)
|
||||||
{
|
{
|
||||||
if (field.Type == TType.Bool)
|
if (field.Type == TType.Bool)
|
||||||
@ -226,11 +224,11 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* The workhorse of WriteFieldBegin. It has the option of doing a
|
/// The workhorse of WriteFieldBegin. It has the option of doing a
|
||||||
* 'type override' of the type header. This is used specifically in the
|
/// 'type override' of the type header. This is used specifically in the
|
||||||
* boolean field case.
|
/// boolean field case.
|
||||||
*/
|
/// </summary>
|
||||||
private void WriteFieldBeginInternal(TField field, byte typeOverride)
|
private void WriteFieldBeginInternal(TField field, byte typeOverride)
|
||||||
{
|
{
|
||||||
// short lastField = lastField_.Pop();
|
// short lastField = lastField_.Pop();
|
||||||
@ -255,18 +253,18 @@ namespace Thrift.Protocol
|
|||||||
// lastField_.push(field.id);
|
// lastField_.push(field.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write the STOP symbol so we know there are no more fields in this struct.
|
/// Write the STOP symbol so we know there are no more fields in this struct.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteFieldStop()
|
public override void WriteFieldStop()
|
||||||
{
|
{
|
||||||
WriteByteDirect(Types.STOP);
|
WriteByteDirect(Types.STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a map header. If the map is empty, omit the key and value type
|
/// Write a map header. If the map is empty, omit the key and value type
|
||||||
* headers, as we don't need any additional information to skip it.
|
/// headers, as we don't need any additional information to skip it.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteMapBegin(TMap map)
|
public override void WriteMapBegin(TMap map)
|
||||||
{
|
{
|
||||||
if (map.Count == 0)
|
if (map.Count == 0)
|
||||||
@ -280,28 +278,28 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a list header.
|
/// Write a list header.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteListBegin(TList list)
|
public override void WriteListBegin(TList list)
|
||||||
{
|
{
|
||||||
WriteCollectionBegin(list.ElementType, list.Count);
|
WriteCollectionBegin(list.ElementType, list.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a set header.
|
/// Write a set header.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteSetBegin(TSet set)
|
public override void WriteSetBegin(TSet set)
|
||||||
{
|
{
|
||||||
WriteCollectionBegin(set.ElementType, set.Count);
|
WriteCollectionBegin(set.ElementType, set.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a boolean value. Potentially, this could be a boolean field, in
|
/// Write a boolean value. Potentially, this could be a boolean field, in
|
||||||
* which case the field header info isn't written yet. If so, decide what the
|
/// which case the field header info isn't written yet. If so, decide what the
|
||||||
* right type header is for the value and then Write the field header.
|
/// right type header is for the value and then Write the field header.
|
||||||
* Otherwise, Write a single byte.
|
/// Otherwise, Write a single byte.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteBool(Boolean b)
|
public override void WriteBool(Boolean b)
|
||||||
{
|
{
|
||||||
if (booleanField_ != null)
|
if (booleanField_ != null)
|
||||||
@ -317,41 +315,41 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a byte. Nothing to see here!
|
/// Write a byte. Nothing to see here!
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteByte(sbyte b)
|
public override void WriteByte(sbyte b)
|
||||||
{
|
{
|
||||||
WriteByteDirect((byte)b);
|
WriteByteDirect((byte)b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write an I16 as a zigzag varint.
|
/// Write an I16 as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteI16(short i16)
|
public override void WriteI16(short i16)
|
||||||
{
|
{
|
||||||
WriteVarint32(intToZigZag(i16));
|
WriteVarint32(intToZigZag(i16));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write an i32 as a zigzag varint.
|
/// Write an i32 as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteI32(int i32)
|
public override void WriteI32(int i32)
|
||||||
{
|
{
|
||||||
WriteVarint32(intToZigZag(i32));
|
WriteVarint32(intToZigZag(i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write an i64 as a zigzag varint.
|
/// Write an i64 as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteI64(long i64)
|
public override void WriteI64(long i64)
|
||||||
{
|
{
|
||||||
WriteVarint64(longToZigzag(i64));
|
WriteVarint64(longToZigzag(i64));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a double to the wire as 8 bytes.
|
/// Write a double to the wire as 8 bytes.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteDouble(double dub)
|
public override void WriteDouble(double dub)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
@ -359,18 +357,18 @@ namespace Thrift.Protocol
|
|||||||
trans.Write(data);
|
trans.Write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a string to the wire with a varint size preceding.
|
/// Write a string to the wire with a varint size preceding.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteString(String str)
|
public override void WriteString(string str)
|
||||||
{
|
{
|
||||||
byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
|
byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
|
||||||
WriteBinary(bytes, 0, bytes.Length);
|
WriteBinary(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write a byte array, using a varint for the size.
|
/// Write a byte array, using a varint for the size.
|
||||||
*/
|
/// </summary>
|
||||||
public override void WriteBinary(byte[] bin)
|
public override void WriteBinary(byte[] bin)
|
||||||
{
|
{
|
||||||
WriteBinary(bin, 0, bin.Length);
|
WriteBinary(bin, 0, bin.Length);
|
||||||
@ -397,10 +395,10 @@ namespace Thrift.Protocol
|
|||||||
// Internal writing methods
|
// Internal writing methods
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Abstract method for writing the start of lists and sets. List and sets on
|
/// Abstract method for writing the start of lists and sets. List and sets on
|
||||||
* the wire differ only by the type indicator.
|
/// the wire differ only by the type indicator.
|
||||||
*/
|
/// </summary>
|
||||||
protected void WriteCollectionBegin(TType elemType, int size)
|
protected void WriteCollectionBegin(TType elemType, int size)
|
||||||
{
|
{
|
||||||
if (size <= 14)
|
if (size <= 14)
|
||||||
@ -414,9 +412,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Write an i64 as a varint. Results in 1-10 bytes on the wire.
|
/// Write an i64 as a varint. Results in 1-10 bytes on the wire.
|
||||||
*/
|
/// </summary>
|
||||||
byte[] varint64out = new byte[10];
|
byte[] varint64out = new byte[10];
|
||||||
private void WriteVarint64(ulong n)
|
private void WriteVarint64(ulong n)
|
||||||
{
|
{
|
||||||
@ -437,28 +435,28 @@ namespace Thrift.Protocol
|
|||||||
trans.Write(varint64out, 0, idx);
|
trans.Write(varint64out, 0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Convert l into a zigzag long. This allows negative numbers to be
|
/// Convert l into a zigzag long. This allows negative numbers to be
|
||||||
* represented compactly as a varint.
|
/// represented compactly as a varint.
|
||||||
*/
|
/// </summary>
|
||||||
private ulong longToZigzag(long n)
|
private ulong longToZigzag(long n)
|
||||||
{
|
{
|
||||||
return (ulong)(n << 1) ^ (ulong)(n >> 63);
|
return (ulong)(n << 1) ^ (ulong)(n >> 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Convert n into a zigzag int. This allows negative numbers to be
|
/// Convert n into a zigzag int. This allows negative numbers to be
|
||||||
* represented compactly as a varint.
|
/// represented compactly as a varint.
|
||||||
*/
|
/// </summary>
|
||||||
private uint intToZigZag(int n)
|
private uint intToZigZag(int n)
|
||||||
{
|
{
|
||||||
return (uint)(n << 1) ^ (uint)(n >> 31);
|
return (uint)(n << 1) ^ (uint)(n >> 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Convert a long into little-endian bytes in buf starting at off and going
|
/// Convert a long into little-endian bytes in buf starting at off and going
|
||||||
* until off+7.
|
/// until off+7.
|
||||||
*/
|
/// </summary>
|
||||||
private void fixedLongToBytes(long n, byte[] buf, int off)
|
private void fixedLongToBytes(long n, byte[] buf, int off)
|
||||||
{
|
{
|
||||||
buf[off + 0] = (byte)(n & 0xff);
|
buf[off + 0] = (byte)(n & 0xff);
|
||||||
@ -475,9 +473,9 @@ namespace Thrift.Protocol
|
|||||||
|
|
||||||
#region ReadMethods
|
#region ReadMethods
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a message header.
|
/// Read a message header.
|
||||||
*/
|
/// </summary>
|
||||||
public override TMessage ReadMessageBegin()
|
public override TMessage ReadMessageBegin()
|
||||||
{
|
{
|
||||||
byte protocolId = (byte)ReadByte();
|
byte protocolId = (byte)ReadByte();
|
||||||
@ -493,14 +491,14 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
|
byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
|
||||||
int seqid = (int)ReadVarint32();
|
int seqid = (int)ReadVarint32();
|
||||||
String messageName = ReadString();
|
string messageName = ReadString();
|
||||||
return new TMessage(messageName, (TMessageType)type, seqid);
|
return new TMessage(messageName, (TMessageType)type, seqid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a struct begin. There's nothing on the wire for this, but it is our
|
/// Read a struct begin. There's nothing on the wire for this, but it is our
|
||||||
* opportunity to push a new struct begin marker onto the field stack.
|
/// opportunity to push a new struct begin marker onto the field stack.
|
||||||
*/
|
/// </summary>
|
||||||
public override TStruct ReadStructBegin()
|
public override TStruct ReadStructBegin()
|
||||||
{
|
{
|
||||||
lastField_.Push(lastFieldId_);
|
lastField_.Push(lastFieldId_);
|
||||||
@ -508,19 +506,19 @@ namespace Thrift.Protocol
|
|||||||
return ANONYMOUS_STRUCT;
|
return ANONYMOUS_STRUCT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Doesn't actually consume any wire data, just removes the last field for
|
/// Doesn't actually consume any wire data, just removes the last field for
|
||||||
* this struct from the field stack.
|
/// this struct from the field stack.
|
||||||
*/
|
/// </summary>
|
||||||
public override void ReadStructEnd()
|
public override void ReadStructEnd()
|
||||||
{
|
{
|
||||||
// consume the last field we Read off the wire.
|
// consume the last field we Read off the wire.
|
||||||
lastFieldId_ = lastField_.Pop();
|
lastFieldId_ = lastField_.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a field header off the wire.
|
/// Read a field header off the wire.
|
||||||
*/
|
/// </summary>
|
||||||
public override TField ReadFieldBegin()
|
public override TField ReadFieldBegin()
|
||||||
{
|
{
|
||||||
byte type = (byte)ReadByte();
|
byte type = (byte)ReadByte();
|
||||||
@ -560,11 +558,11 @@ namespace Thrift.Protocol
|
|||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a map header off the wire. If the size is zero, skip Reading the key
|
/// Read a map header off the wire. If the size is zero, skip Reading the key
|
||||||
* and value type. This means that 0-length maps will yield TMaps without the
|
/// and value type. This means that 0-length maps will yield TMaps without the
|
||||||
* "correct" types.
|
/// "correct" types.
|
||||||
*/
|
/// </summary>
|
||||||
public override TMap ReadMapBegin()
|
public override TMap ReadMapBegin()
|
||||||
{
|
{
|
||||||
int size = (int)ReadVarint32();
|
int size = (int)ReadVarint32();
|
||||||
@ -572,12 +570,12 @@ namespace Thrift.Protocol
|
|||||||
return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
|
return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a list header off the wire. If the list size is 0-14, the size will
|
/// Read a list header off the wire. If the list size is 0-14, the size will
|
||||||
* be packed into the element type header. If it's a longer list, the 4 MSB
|
/// be packed into the element type header. If it's a longer list, the 4 MSB
|
||||||
* of the element type header will be 0xF, and a varint will follow with the
|
/// of the element type header will be 0xF, and a varint will follow with the
|
||||||
* true size.
|
/// true size.
|
||||||
*/
|
/// </summary>
|
||||||
public override TList ReadListBegin()
|
public override TList ReadListBegin()
|
||||||
{
|
{
|
||||||
byte size_and_type = (byte)ReadByte();
|
byte size_and_type = (byte)ReadByte();
|
||||||
@ -590,22 +588,22 @@ namespace Thrift.Protocol
|
|||||||
return new TList(type, size);
|
return new TList(type, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a set header off the wire. If the set size is 0-14, the size will
|
/// Read a set header off the wire. If the set size is 0-14, the size will
|
||||||
* be packed into the element type header. If it's a longer set, the 4 MSB
|
/// be packed into the element type header. If it's a longer set, the 4 MSB
|
||||||
* of the element type header will be 0xF, and a varint will follow with the
|
/// of the element type header will be 0xF, and a varint will follow with the
|
||||||
* true size.
|
/// true size.
|
||||||
*/
|
/// </summary>
|
||||||
public override TSet ReadSetBegin()
|
public override TSet ReadSetBegin()
|
||||||
{
|
{
|
||||||
return new TSet(ReadListBegin());
|
return new TSet(ReadListBegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a boolean off the wire. If this is a boolean field, the value should
|
/// Read a boolean off the wire. If this is a boolean field, the value should
|
||||||
* already have been Read during ReadFieldBegin, so we'll just consume the
|
/// already have been Read during ReadFieldBegin, so we'll just consume the
|
||||||
* pre-stored value. Otherwise, Read a byte.
|
/// pre-stored value. Otherwise, Read a byte.
|
||||||
*/
|
/// </summary>
|
||||||
public override Boolean ReadBool()
|
public override Boolean ReadBool()
|
||||||
{
|
{
|
||||||
if (boolValue_ != null)
|
if (boolValue_ != null)
|
||||||
@ -618,42 +616,42 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte[] byteRawBuf = new byte[1];
|
byte[] byteRawBuf = new byte[1];
|
||||||
/**
|
/// <summary>
|
||||||
* Read a single byte off the wire. Nothing interesting here.
|
/// Read a single byte off the wire. Nothing interesting here.
|
||||||
*/
|
/// </summary>
|
||||||
public override sbyte ReadByte()
|
public override sbyte ReadByte()
|
||||||
{
|
{
|
||||||
trans.ReadAll(byteRawBuf, 0, 1);
|
trans.ReadAll(byteRawBuf, 0, 1);
|
||||||
return (sbyte)byteRawBuf[0];
|
return (sbyte)byteRawBuf[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read an i16 from the wire as a zigzag varint.
|
/// Read an i16 from the wire as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override short ReadI16()
|
public override short ReadI16()
|
||||||
{
|
{
|
||||||
return (short)zigzagToInt(ReadVarint32());
|
return (short)zigzagToInt(ReadVarint32());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read an i32 from the wire as a zigzag varint.
|
/// Read an i32 from the wire as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override int ReadI32()
|
public override int ReadI32()
|
||||||
{
|
{
|
||||||
return zigzagToInt(ReadVarint32());
|
return zigzagToInt(ReadVarint32());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read an i64 from the wire as a zigzag varint.
|
/// Read an i64 from the wire as a zigzag varint.
|
||||||
*/
|
/// </summary>
|
||||||
public override long ReadI64()
|
public override long ReadI64()
|
||||||
{
|
{
|
||||||
return zigzagToLong(ReadVarint64());
|
return zigzagToLong(ReadVarint64());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* No magic here - just Read a double off the wire.
|
/// No magic here - just Read a double off the wire.
|
||||||
*/
|
/// </summary>
|
||||||
public override double ReadDouble()
|
public override double ReadDouble()
|
||||||
{
|
{
|
||||||
byte[] longBits = new byte[8];
|
byte[] longBits = new byte[8];
|
||||||
@ -661,10 +659,10 @@ namespace Thrift.Protocol
|
|||||||
return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
|
return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
|
/// Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
|
||||||
*/
|
/// </summary>
|
||||||
public override String ReadString()
|
public override string ReadString()
|
||||||
{
|
{
|
||||||
int length = (int)ReadVarint32();
|
int length = (int)ReadVarint32();
|
||||||
|
|
||||||
@ -676,9 +674,9 @@ namespace Thrift.Protocol
|
|||||||
return Encoding.UTF8.GetString(ReadBinary(length));
|
return Encoding.UTF8.GetString(ReadBinary(length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a byte[] from the wire.
|
/// Read a byte[] from the wire.
|
||||||
*/
|
/// </summary>
|
||||||
public override byte[] ReadBinary()
|
public override byte[] ReadBinary()
|
||||||
{
|
{
|
||||||
int length = (int)ReadVarint32();
|
int length = (int)ReadVarint32();
|
||||||
@ -689,9 +687,9 @@ namespace Thrift.Protocol
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read a byte[] of a known length from the wire.
|
/// Read a byte[] of a known length from the wire.
|
||||||
*/
|
/// </summary>
|
||||||
private byte[] ReadBinary(int length)
|
private byte[] ReadBinary(int length)
|
||||||
{
|
{
|
||||||
if (length == 0) return new byte[0];
|
if (length == 0) return new byte[0];
|
||||||
@ -715,10 +713,10 @@ namespace Thrift.Protocol
|
|||||||
// Internal Reading methods
|
// Internal Reading methods
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read an i32 from the wire as a varint. The MSB of each byte is set
|
/// Read an i32 from the wire as a varint. The MSB of each byte is set
|
||||||
* if there is another byte to follow. This can Read up to 5 bytes.
|
/// if there is another byte to follow. This can Read up to 5 bytes.
|
||||||
*/
|
/// </summary>
|
||||||
private uint ReadVarint32()
|
private uint ReadVarint32()
|
||||||
{
|
{
|
||||||
uint result = 0;
|
uint result = 0;
|
||||||
@ -733,10 +731,10 @@ namespace Thrift.Protocol
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Read an i64 from the wire as a proper varint. The MSB of each byte is set
|
/// Read an i64 from the wire as a proper varint. The MSB of each byte is set
|
||||||
* if there is another byte to follow. This can Read up to 10 bytes.
|
/// if there is another byte to follow. This can Read up to 10 bytes.
|
||||||
*/
|
/// </summary>
|
||||||
private ulong ReadVarint64()
|
private ulong ReadVarint64()
|
||||||
{
|
{
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
@ -758,27 +756,27 @@ namespace Thrift.Protocol
|
|||||||
// encoding helpers
|
// encoding helpers
|
||||||
//
|
//
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Convert from zigzag int to int.
|
/// Convert from zigzag int to int.
|
||||||
*/
|
/// </summary>
|
||||||
private int zigzagToInt(uint n)
|
private int zigzagToInt(uint n)
|
||||||
{
|
{
|
||||||
return (int)(n >> 1) ^ (-(int)(n & 1));
|
return (int)(n >> 1) ^ (-(int)(n & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Convert from zigzag long to long.
|
/// Convert from zigzag long to long.
|
||||||
*/
|
/// </summary>
|
||||||
private long zigzagToLong(ulong n)
|
private long zigzagToLong(ulong n)
|
||||||
{
|
{
|
||||||
return (long)(n >> 1) ^ (-(long)(n & 1));
|
return (long)(n >> 1) ^ (-(long)(n & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Note that it's important that the mask bytes are long literals,
|
/// Note that it's important that the mask bytes are long literals,
|
||||||
* otherwise they'll default to ints, and when you shift an int left 56 bits,
|
/// otherwise they'll default to ints, and when you shift an int left 56 bits,
|
||||||
* you just get a messed up int.
|
/// you just get a messed up int.
|
||||||
*/
|
/// </summary>
|
||||||
private long bytesToLong(byte[] bytes)
|
private long bytesToLong(byte[] bytes)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
@ -802,10 +800,10 @@ namespace Thrift.Protocol
|
|||||||
return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
|
return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Given a TCompactProtocol.Types constant, convert it to its corresponding
|
/// Given a TCompactProtocol.Types constant, convert it to its corresponding
|
||||||
* TType value.
|
/// TType value.
|
||||||
*/
|
/// </summary>
|
||||||
private TType getTType(byte type)
|
private TType getTType(byte type)
|
||||||
{
|
{
|
||||||
switch ((byte)(type & 0x0f))
|
switch ((byte)(type & 0x0f))
|
||||||
@ -840,9 +838,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Given a TType value, find the appropriate TCompactProtocol.Types constant.
|
/// Given a TType value, find the appropriate TCompactProtocol.Types constant.
|
||||||
*/
|
/// </summary>
|
||||||
private byte getCompactType(TType ttype)
|
private byte getCompactType(TType ttype)
|
||||||
{
|
{
|
||||||
return ttypeToCompactType[(int)ttype];
|
return ttypeToCompactType[(int)ttype];
|
||||||
|
@ -29,18 +29,18 @@ namespace Thrift.Protocol
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// JSON protocol implementation for thrift.
|
/// JSON protocol implementation for thrift.
|
||||||
///
|
/// <para/>
|
||||||
/// This is a full-featured protocol supporting Write and Read.
|
/// This is a full-featured protocol supporting Write and Read.
|
||||||
///
|
/// <para/>
|
||||||
/// Please see the C++ class header for a detailed description of the
|
/// Please see the C++ class header for a detailed description of the
|
||||||
/// protocol's wire format.
|
/// protocol's wire format.
|
||||||
///
|
/// <para/>
|
||||||
/// Adapted from the Java version.
|
/// Adapted from the Java version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TJSONProtocol : TProtocol
|
public class TJSONProtocol : TProtocol
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Factory for JSON protocol objects
|
/// Factory for JSON protocol objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Factory : TProtocolFactory
|
public class Factory : TProtocolFactory
|
||||||
{
|
{
|
||||||
@ -179,11 +179,11 @@ namespace Thrift.Protocol
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Base class for tracking JSON contexts that may require
|
/// Base class for tracking JSON contexts that may require
|
||||||
/// inserting/Reading additional JSON syntax characters
|
/// inserting/Reading additional JSON syntax characters
|
||||||
/// This base context does nothing.
|
/// This base context does nothing.
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected class JSONBaseContext
|
protected class JSONBaseContext
|
||||||
{
|
{
|
||||||
protected TJSONProtocol proto;
|
protected TJSONProtocol proto;
|
||||||
@ -200,10 +200,10 @@ namespace Thrift.Protocol
|
|||||||
public virtual bool EscapeNumbers() { return false; }
|
public virtual bool EscapeNumbers() { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Context for JSON lists. Will insert/Read commas before each item except
|
/// Context for JSON lists. Will insert/Read commas before each item except
|
||||||
/// for the first one
|
/// for the first one
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected class JSONListContext : JSONBaseContext
|
protected class JSONListContext : JSONBaseContext
|
||||||
{
|
{
|
||||||
public JSONListContext(TJSONProtocol protocol)
|
public JSONListContext(TJSONProtocol protocol)
|
||||||
@ -239,12 +239,12 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Context for JSON records. Will insert/Read colons before the value portion
|
/// Context for JSON records. Will insert/Read colons before the value portion
|
||||||
/// of each record pair, and commas before each key except the first. In
|
/// of each record pair, and commas before each key except the first. In
|
||||||
/// addition, will indicate that numbers in the key position need to be
|
/// addition, will indicate that numbers in the key position need to be
|
||||||
/// escaped in quotes (since JSON keys must be strings).
|
/// escaped in quotes (since JSON keys must be strings).
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected class JSONPairContext : JSONBaseContext
|
protected class JSONPairContext : JSONBaseContext
|
||||||
{
|
{
|
||||||
public JSONPairContext(TJSONProtocol proto)
|
public JSONPairContext(TJSONProtocol proto)
|
||||||
@ -290,9 +290,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Holds up to one byte from the transport
|
/// Holds up to one byte from the transport
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected class LookaheadReader
|
protected class LookaheadReader
|
||||||
{
|
{
|
||||||
protected TJSONProtocol proto;
|
protected TJSONProtocol proto;
|
||||||
@ -305,10 +305,10 @@ namespace Thrift.Protocol
|
|||||||
private bool hasData;
|
private bool hasData;
|
||||||
private byte[] data = new byte[1];
|
private byte[] data = new byte[1];
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Return and consume the next byte to be Read, either taking it from the
|
/// Return and consume the next byte to be Read, either taking it from the
|
||||||
/// data buffer if present or getting it from the transport otherwise.
|
/// data buffer if present or getting it from the transport otherwise.
|
||||||
///</summary>
|
/// </summary>
|
||||||
public byte Read()
|
public byte Read()
|
||||||
{
|
{
|
||||||
if (hasData)
|
if (hasData)
|
||||||
@ -322,10 +322,10 @@ namespace Thrift.Protocol
|
|||||||
return data[0];
|
return data[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Return the next byte to be Read without consuming, filling the data
|
/// Return the next byte to be Read without consuming, filling the data
|
||||||
/// buffer if it has not been filled alReady.
|
/// buffer if it has not been filled alReady.
|
||||||
///</summary>
|
/// </summary>
|
||||||
public byte Peek()
|
public byte Peek()
|
||||||
{
|
{
|
||||||
if (!hasData)
|
if (!hasData)
|
||||||
@ -349,26 +349,26 @@ namespace Thrift.Protocol
|
|||||||
// Reader that manages a 1-byte buffer
|
// Reader that manages a 1-byte buffer
|
||||||
protected LookaheadReader reader;
|
protected LookaheadReader reader;
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Push a new JSON context onto the stack.
|
/// Push a new JSON context onto the stack.
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected void PushContext(JSONBaseContext c)
|
protected void PushContext(JSONBaseContext c)
|
||||||
{
|
{
|
||||||
contextStack.Push(context);
|
contextStack.Push(context);
|
||||||
context = c;
|
context = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Pop the last JSON context off the stack
|
/// Pop the last JSON context off the stack
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected void PopContext()
|
protected void PopContext()
|
||||||
{
|
{
|
||||||
context = contextStack.Pop();
|
context = contextStack.Pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// TJSONProtocol Constructor
|
/// TJSONProtocol Constructor
|
||||||
///</summary>
|
/// </summary>
|
||||||
public TJSONProtocol(TTransport trans)
|
public TJSONProtocol(TTransport trans)
|
||||||
: base(trans)
|
: base(trans)
|
||||||
{
|
{
|
||||||
@ -379,11 +379,11 @@ namespace Thrift.Protocol
|
|||||||
// Temporary buffer used by several methods
|
// Temporary buffer used by several methods
|
||||||
private byte[] tempBuffer = new byte[4];
|
private byte[] tempBuffer = new byte[4];
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Read a byte that must match b[0]; otherwise an exception is thrown.
|
/// Read a byte that must match b[0]; otherwise an exception is thrown.
|
||||||
/// Marked protected to avoid synthetic accessor in JSONListContext.Read
|
/// Marked protected to avoid synthetic accessor in JSONListContext.Read
|
||||||
/// and JSONPairContext.Read
|
/// and JSONPairContext.Read
|
||||||
///</summary>
|
/// </summary>
|
||||||
protected void ReadJSONSyntaxChar(byte[] b)
|
protected void ReadJSONSyntaxChar(byte[] b)
|
||||||
{
|
{
|
||||||
byte ch = reader.Read();
|
byte ch = reader.Read();
|
||||||
@ -394,10 +394,10 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
|
/// Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its
|
||||||
/// corresponding hex value
|
/// corresponding hex value
|
||||||
///</summary>
|
/// </summary>
|
||||||
private static byte HexVal(byte ch)
|
private static byte HexVal(byte ch)
|
||||||
{
|
{
|
||||||
if ((ch >= '0') && (ch <= '9'))
|
if ((ch >= '0') && (ch <= '9'))
|
||||||
@ -416,9 +416,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Convert a byte containing a hex value to its corresponding hex character
|
/// Convert a byte containing a hex value to its corresponding hex character
|
||||||
///</summary>
|
/// </summary>
|
||||||
private static byte HexChar(byte val)
|
private static byte HexChar(byte val)
|
||||||
{
|
{
|
||||||
val &= 0x0F;
|
val &= 0x0F;
|
||||||
@ -433,9 +433,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Write the bytes in array buf as a JSON characters, escaping as needed
|
/// Write the bytes in array buf as a JSON characters, escaping as needed
|
||||||
///</summary>
|
/// </summary>
|
||||||
private void WriteJSONString(byte[] b)
|
private void WriteJSONString(byte[] b)
|
||||||
{
|
{
|
||||||
context.Write();
|
context.Write();
|
||||||
@ -479,14 +479,14 @@ namespace Thrift.Protocol
|
|||||||
trans.Write(QUOTE);
|
trans.Write(QUOTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Write out number as a JSON value. If the context dictates so, it will be
|
/// Write out number as a JSON value. If the context dictates so, it will be
|
||||||
/// wrapped in quotes to output as a JSON string.
|
/// wrapped in quotes to output as a JSON string.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private void WriteJSONInteger(long num)
|
private void WriteJSONInteger(long num)
|
||||||
{
|
{
|
||||||
context.Write();
|
context.Write();
|
||||||
String str = num.ToString();
|
string str = num.ToString();
|
||||||
|
|
||||||
bool escapeNum = context.EscapeNumbers();
|
bool escapeNum = context.EscapeNumbers();
|
||||||
if (escapeNum)
|
if (escapeNum)
|
||||||
@ -498,14 +498,14 @@ namespace Thrift.Protocol
|
|||||||
trans.Write(QUOTE);
|
trans.Write(QUOTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Write out a double as a JSON value. If it is NaN or infinity or if the
|
/// Write out a double as a JSON value. If it is NaN or infinity or if the
|
||||||
/// context dictates escaping, Write out as JSON string.
|
/// context dictates escaping, Write out as JSON string.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private void WriteJSONDouble(double num)
|
private void WriteJSONDouble(double num)
|
||||||
{
|
{
|
||||||
context.Write();
|
context.Write();
|
||||||
String str = num.ToString("G17", CultureInfo.InvariantCulture);
|
string str = num.ToString("G17", CultureInfo.InvariantCulture);
|
||||||
bool special = false;
|
bool special = false;
|
||||||
|
|
||||||
switch (str[0])
|
switch (str[0])
|
||||||
@ -532,10 +532,10 @@ namespace Thrift.Protocol
|
|||||||
if (escapeNum)
|
if (escapeNum)
|
||||||
trans.Write(QUOTE);
|
trans.Write(QUOTE);
|
||||||
}
|
}
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Write out contents of byte array b as a JSON string with base-64 encoded
|
/// Write out contents of byte array b as a JSON string with base-64 encoded
|
||||||
/// data
|
/// data
|
||||||
///</summary>
|
/// </summary>
|
||||||
private void WriteJSONBase64(byte[] b)
|
private void WriteJSONBase64(byte[] b)
|
||||||
{
|
{
|
||||||
context.Write();
|
context.Write();
|
||||||
@ -698,7 +698,7 @@ namespace Thrift.Protocol
|
|||||||
WriteJSONDouble(dub);
|
WriteJSONDouble(dub);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteString(String str)
|
public override void WriteString(string str)
|
||||||
{
|
{
|
||||||
byte[] b = utf8Encoding.GetBytes(str);
|
byte[] b = utf8Encoding.GetBytes(str);
|
||||||
WriteJSONString(b);
|
WriteJSONString(b);
|
||||||
@ -713,10 +713,10 @@ namespace Thrift.Protocol
|
|||||||
* Reading methods.
|
* Reading methods.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
|
/// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
|
||||||
/// context if skipContext is true.
|
/// context if skipContext is true.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private byte[] ReadJSONString(bool skipContext)
|
private byte[] ReadJSONString(bool skipContext)
|
||||||
{
|
{
|
||||||
MemoryStream buffer = new MemoryStream();
|
MemoryStream buffer = new MemoryStream();
|
||||||
@ -803,9 +803,9 @@ namespace Thrift.Protocol
|
|||||||
return buffer.ToArray();
|
return buffer.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Return true if the given byte could be a valid part of a JSON number.
|
/// Return true if the given byte could be a valid part of a JSON number.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private bool IsJSONNumeric(byte b)
|
private bool IsJSONNumeric(byte b)
|
||||||
{
|
{
|
||||||
switch (b)
|
switch (b)
|
||||||
@ -830,11 +830,11 @@ namespace Thrift.Protocol
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Read in a sequence of characters that are all valid in JSON numbers. Does
|
/// Read in a sequence of characters that are all valid in JSON numbers. Does
|
||||||
/// not do a complete regex check to validate that this is actually a number.
|
/// not do a complete regex check to validate that this is actually a number.
|
||||||
////</summary>
|
/// </summary>
|
||||||
private String ReadJSONNumericChars()
|
private string ReadJSONNumericChars()
|
||||||
{
|
{
|
||||||
StringBuilder strbld = new StringBuilder();
|
StringBuilder strbld = new StringBuilder();
|
||||||
while (true)
|
while (true)
|
||||||
@ -849,9 +849,9 @@ namespace Thrift.Protocol
|
|||||||
return strbld.ToString();
|
return strbld.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Read in a JSON number. If the context dictates, Read in enclosing quotes.
|
/// Read in a JSON number. If the context dictates, Read in enclosing quotes.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private long ReadJSONInteger()
|
private long ReadJSONInteger()
|
||||||
{
|
{
|
||||||
context.Read();
|
context.Read();
|
||||||
@ -859,7 +859,7 @@ namespace Thrift.Protocol
|
|||||||
{
|
{
|
||||||
ReadJSONSyntaxChar(QUOTE);
|
ReadJSONSyntaxChar(QUOTE);
|
||||||
}
|
}
|
||||||
String str = ReadJSONNumericChars();
|
string str = ReadJSONNumericChars();
|
||||||
if (context.EscapeNumbers())
|
if (context.EscapeNumbers())
|
||||||
{
|
{
|
||||||
ReadJSONSyntaxChar(QUOTE);
|
ReadJSONSyntaxChar(QUOTE);
|
||||||
@ -875,17 +875,17 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///<summary>
|
/// <summary>
|
||||||
/// Read in a JSON double value. Throw if the value is not wrapped in quotes
|
/// Read in a JSON double value. Throw if the value is not wrapped in quotes
|
||||||
/// when expected or if wrapped in quotes when not expected.
|
/// when expected or if wrapped in quotes when not expected.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private double ReadJSONDouble()
|
private double ReadJSONDouble()
|
||||||
{
|
{
|
||||||
context.Read();
|
context.Read();
|
||||||
if (reader.Peek() == QUOTE[0])
|
if (reader.Peek() == QUOTE[0])
|
||||||
{
|
{
|
||||||
byte[] arr = ReadJSONString(true);
|
byte[] arr = ReadJSONString(true);
|
||||||
double dub = Double.Parse(utf8Encoding.GetString(arr,0,arr.Length), CultureInfo.InvariantCulture);
|
double dub = Double.Parse(utf8Encoding.GetString(arr, 0, arr.Length), CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
if (!context.EscapeNumbers() && !Double.IsNaN(dub) &&
|
if (!context.EscapeNumbers() && !Double.IsNaN(dub) &&
|
||||||
!Double.IsInfinity(dub))
|
!Double.IsInfinity(dub))
|
||||||
@ -915,9 +915,9 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//<summary>
|
/// <summary>
|
||||||
/// Read in a JSON string containing base-64 encoded data and decode it.
|
/// Read in a JSON string containing base-64 encoded data and decode it.
|
||||||
///</summary>
|
/// </summary>
|
||||||
private byte[] ReadJSONBase64()
|
private byte[] ReadJSONBase64()
|
||||||
{
|
{
|
||||||
byte[] b = ReadJSONString(false);
|
byte[] b = ReadJSONString(false);
|
||||||
@ -989,7 +989,7 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
var buf = ReadJSONString(false);
|
var buf = ReadJSONString(false);
|
||||||
message.Name = utf8Encoding.GetString(buf,0,buf.Length);
|
message.Name = utf8Encoding.GetString(buf, 0, buf.Length);
|
||||||
message.Type = (TMessageType)ReadJSONInteger();
|
message.Type = (TMessageType)ReadJSONInteger();
|
||||||
message.SeqID = (int)ReadJSONInteger();
|
message.SeqID = (int)ReadJSONInteger();
|
||||||
return message;
|
return message;
|
||||||
@ -1108,10 +1108,10 @@ namespace Thrift.Protocol
|
|||||||
return ReadJSONDouble();
|
return ReadJSONDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override String ReadString()
|
public override string ReadString()
|
||||||
{
|
{
|
||||||
var buf = ReadJSONString(false);
|
var buf = ReadJSONString(false);
|
||||||
return utf8Encoding.GetString(buf,0,buf.Length);
|
return utf8Encoding.GetString(buf, 0, buf.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadBinary()
|
public override byte[] ReadBinary()
|
||||||
|
@ -29,74 +29,77 @@ using System.IO;
|
|||||||
|
|
||||||
namespace Thrift.Protocol
|
namespace Thrift.Protocol
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
/**
|
/// <see cref="TMultiplexedProcessor"/> is a <see cref="TProcessor"/> allowing a single <see cref="Thrift.Server.TServer"/>
|
||||||
* TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services.
|
/// to provide multiple services.
|
||||||
* To do so, you instantiate the processor and then register additional processors with it,
|
/// <para/>
|
||||||
* as shown in the following example:
|
/// To do so, you instantiate the processor and then register additional processors with it,
|
||||||
*
|
/// as shown in the following example:
|
||||||
* TMultiplexedProcessor processor = new TMultiplexedProcessor();
|
/// <para/>
|
||||||
*
|
/// <code>
|
||||||
* processor.registerProcessor(
|
/// TMultiplexedProcessor processor = new TMultiplexedProcessor();
|
||||||
* "Calculator",
|
///
|
||||||
* new Calculator.Processor(new CalculatorHandler()));
|
/// processor.registerProcessor(
|
||||||
*
|
/// "Calculator",
|
||||||
* processor.registerProcessor(
|
/// new Calculator.Processor(new CalculatorHandler()));
|
||||||
* "WeatherReport",
|
///
|
||||||
* new WeatherReport.Processor(new WeatherReportHandler()));
|
/// processor.registerProcessor(
|
||||||
*
|
/// "WeatherReport",
|
||||||
* TServerTransport t = new TServerSocket(9090);
|
/// new WeatherReport.Processor(new WeatherReportHandler()));
|
||||||
* TSimpleServer server = new TSimpleServer(processor, t);
|
///
|
||||||
*
|
/// TServerTransport t = new TServerSocket(9090);
|
||||||
* server.serve();
|
/// TSimpleServer server = new TSimpleServer(processor, t);
|
||||||
*/
|
///
|
||||||
|
/// server.serve();
|
||||||
|
/// </code>
|
||||||
|
/// </summary>
|
||||||
public class TMultiplexedProcessor : TProcessor
|
public class TMultiplexedProcessor : TProcessor
|
||||||
{
|
{
|
||||||
private Dictionary<String,TProcessor> ServiceProcessorMap = new Dictionary<String,TProcessor>();
|
private Dictionary<string, TProcessor> ServiceProcessorMap = new Dictionary<string, TProcessor>();
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* 'Register' a service with this TMultiplexedProcessor. This allows us to broker
|
/// 'Register' a service with this TMultiplexedProcessor. This allows us to broker
|
||||||
* requests to individual services by using the service name to select them at request time.
|
/// requests to individual services by using the service name to select them at request time.
|
||||||
*
|
///
|
||||||
* Args:
|
/// Args:
|
||||||
* - serviceName Name of a service, has to be identical to the name
|
/// - serviceName Name of a service, has to be identical to the name
|
||||||
* declared in the Thrift IDL, e.g. "WeatherReport".
|
/// declared in the Thrift IDL, e.g. "WeatherReport".
|
||||||
* - processor Implementation of a service, usually referred to as "handlers",
|
/// - processor Implementation of a service, usually referred to as "handlers",
|
||||||
* e.g. WeatherReportHandler implementing WeatherReport.Iface.
|
/// e.g. WeatherReportHandler implementing WeatherReport.Iface.
|
||||||
*/
|
/// </summary>
|
||||||
public void RegisterProcessor(String serviceName, TProcessor processor)
|
public void RegisterProcessor(string serviceName, TProcessor processor)
|
||||||
{
|
{
|
||||||
ServiceProcessorMap.Add(serviceName, processor);
|
ServiceProcessorMap.Add(serviceName, processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Fail( TProtocol oprot, TMessage message, TApplicationException.ExceptionType extype, string etxt)
|
private void Fail(TProtocol oprot, TMessage message, TApplicationException.ExceptionType extype, string etxt)
|
||||||
{
|
{
|
||||||
TApplicationException appex = new TApplicationException( extype, etxt);
|
TApplicationException appex = new TApplicationException(extype, etxt);
|
||||||
|
|
||||||
TMessage newMessage = new TMessage(message.Name, TMessageType.Exception, message.SeqID);
|
TMessage newMessage = new TMessage(message.Name, TMessageType.Exception, message.SeqID);
|
||||||
|
|
||||||
oprot.WriteMessageBegin(newMessage);
|
oprot.WriteMessageBegin(newMessage);
|
||||||
appex.Write( oprot);
|
appex.Write(oprot);
|
||||||
oprot.WriteMessageEnd();
|
oprot.WriteMessageEnd();
|
||||||
oprot.Transport.Flush();
|
oprot.Transport.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* This implementation of process performs the following steps:
|
/// This implementation of process performs the following steps:
|
||||||
*
|
///
|
||||||
* - Read the beginning of the message.
|
/// - Read the beginning of the message.
|
||||||
* - Extract the service name from the message.
|
/// - Extract the service name from the message.
|
||||||
* - Using the service name to locate the appropriate processor.
|
/// - Using the service name to locate the appropriate processor.
|
||||||
* - Dispatch to the processor, with a decorated instance of TProtocol
|
/// - Dispatch to the processor, with a decorated instance of TProtocol
|
||||||
* that allows readMessageBegin() to return the original TMessage.
|
/// that allows readMessageBegin() to return the original TMessage.
|
||||||
*
|
/// <para/>
|
||||||
* Throws an exception if
|
/// Throws an exception if
|
||||||
* - the message type is not CALL or ONEWAY,
|
/// - the message type is not CALL or ONEWAY,
|
||||||
* - the service name was not found in the message, or
|
/// - the service name was not found in the message, or
|
||||||
* - the service name has not been RegisterProcessor()ed.
|
/// - the service name has not been RegisterProcessor()ed.
|
||||||
*/
|
/// </summary>
|
||||||
public bool Process(TProtocol iprot, TProtocol oprot)
|
public bool Process(TProtocol iprot, TProtocol oprot)
|
||||||
{
|
{
|
||||||
/* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
|
/* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
|
||||||
@ -155,17 +158,17 @@ namespace Thrift.Protocol
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Our goal was to work with any protocol. In order to do that, we needed
|
/// Our goal was to work with any protocol. In order to do that, we needed
|
||||||
* to allow them to call readMessageBegin() and get a TMessage in exactly
|
/// to allow them to call readMessageBegin() and get a TMessage in exactly
|
||||||
* the standard format, without the service name prepended to TMessage.name.
|
/// the standard format, without the service name prepended to TMessage.name.
|
||||||
*/
|
/// </summary>
|
||||||
private class StoredMessageProtocol : TProtocolDecorator
|
private class StoredMessageProtocol : TProtocolDecorator
|
||||||
{
|
{
|
||||||
TMessage MsgBegin;
|
TMessage MsgBegin;
|
||||||
|
|
||||||
public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin)
|
public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin)
|
||||||
:base(protocol)
|
: base(protocol)
|
||||||
{
|
{
|
||||||
this.MsgBegin = messageBegin;
|
this.MsgBegin = messageBegin;
|
||||||
}
|
}
|
||||||
|
@ -29,63 +29,62 @@ using System.Collections.Generic;
|
|||||||
namespace Thrift.Protocol
|
namespace Thrift.Protocol
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
|
/// TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
|
||||||
* client to communicate with a multiplexing Thrift server, by prepending the service name
|
/// client to communicate with a multiplexing Thrift server, by prepending the service name
|
||||||
* to the function name during function calls.
|
/// to the function name during function calls.
|
||||||
*
|
/// <para/>
|
||||||
* NOTE: THIS IS NOT TO BE USED BY SERVERS.
|
/// NOTE: THIS IS NOT TO BE USED BY SERVERS.
|
||||||
* On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
|
/// On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
|
||||||
*
|
/// <para/>
|
||||||
* This example uses a single socket transport to invoke two services:
|
/// This example uses a single socket transport to invoke two services:
|
||||||
*
|
/// <code>
|
||||||
* TSocket transport = new TSocket("localhost", 9090);
|
/// TSocket transport = new TSocket("localhost", 9090);
|
||||||
* transport.open();
|
/// transport.open();
|
||||||
*
|
///
|
||||||
* TBinaryProtocol protocol = new TBinaryProtocol(transport);
|
/// TBinaryProtocol protocol = new TBinaryProtocol(transport);
|
||||||
*
|
///
|
||||||
* TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
|
/// TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
|
||||||
* Calculator.Client service = new Calculator.Client(mp);
|
/// Calculator.Client service = new Calculator.Client(mp);
|
||||||
*
|
///
|
||||||
* TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
|
/// TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
|
||||||
* WeatherReport.Client service2 = new WeatherReport.Client(mp2);
|
/// WeatherReport.Client service2 = new WeatherReport.Client(mp2);
|
||||||
*
|
///
|
||||||
* System.out.println(service.add(2,2));
|
/// System.out.println(service.add(2,2));
|
||||||
* System.out.println(service2.getTemperature());
|
/// System.out.println(service2.getTemperature());
|
||||||
*
|
/// </code>
|
||||||
*/
|
/// </summary>
|
||||||
public class TMultiplexedProtocol : TProtocolDecorator
|
public class TMultiplexedProtocol : TProtocolDecorator
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Used to delimit the service name from the function name */
|
/// <summary>
|
||||||
public static String SEPARATOR = ":";
|
/// Used to delimit the service name from the function name.
|
||||||
|
/// </summary>
|
||||||
|
public static string SEPARATOR = ":";
|
||||||
|
|
||||||
private String ServiceName;
|
private string ServiceName;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Wrap the specified protocol, allowing it to be used to communicate with a
|
/// Wrap the specified protocol, allowing it to be used to communicate with a
|
||||||
* multiplexing server. The <code>serviceName</code> is required as it is
|
/// multiplexing server. The <paramref name="serviceName"/> is required as it is
|
||||||
* prepended to the message header so that the multiplexing server can broker
|
/// prepended to the message header so that the multiplexing server can broker
|
||||||
* the function call to the proper service.
|
/// the function call to the proper service.
|
||||||
*
|
/// </summary>
|
||||||
* Args:
|
/// <param name="protocol">Your communication protocol of choice, e.g. <see cref="TBinaryProtocol"/>.</param>
|
||||||
* protocol Your communication protocol of choice, e.g. TBinaryProtocol
|
/// <param name="serviceName">The service name of the service communicating via this protocol.</param>
|
||||||
* serviceName The service name of the service communicating via this protocol.
|
public TMultiplexedProtocol(TProtocol protocol, string serviceName)
|
||||||
*/
|
|
||||||
public TMultiplexedProtocol(TProtocol protocol, String serviceName)
|
|
||||||
: base(protocol)
|
: base(protocol)
|
||||||
{
|
{
|
||||||
ServiceName = serviceName;
|
ServiceName = serviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
|
/// Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
|
||||||
* Args:
|
/// </summary>
|
||||||
* tMessage The original message.
|
/// <param name="tMessage">The original message.</param>
|
||||||
*/
|
|
||||||
public override void WriteMessageBegin(TMessage tMessage)
|
public override void WriteMessageBegin(TMessage tMessage)
|
||||||
{
|
{
|
||||||
switch(tMessage.Type)
|
switch (tMessage.Type)
|
||||||
{
|
{
|
||||||
case TMessageType.Call:
|
case TMessageType.Call:
|
||||||
case TMessageType.Oneway:
|
case TMessageType.Oneway:
|
||||||
@ -101,5 +100,4 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,8 @@ namespace Thrift.Protocol
|
|||||||
public abstract void WriteI32(int i32);
|
public abstract void WriteI32(int i32);
|
||||||
public abstract void WriteI64(long i64);
|
public abstract void WriteI64(long i64);
|
||||||
public abstract void WriteDouble(double d);
|
public abstract void WriteDouble(double d);
|
||||||
public virtual void WriteString(string s) {
|
public virtual void WriteString(string s)
|
||||||
|
{
|
||||||
WriteBinary(Encoding.UTF8.GetBytes(s));
|
WriteBinary(Encoding.UTF8.GetBytes(s));
|
||||||
}
|
}
|
||||||
public abstract void WriteBinary(byte[] b);
|
public abstract void WriteBinary(byte[] b);
|
||||||
@ -131,7 +132,8 @@ namespace Thrift.Protocol
|
|||||||
public abstract int ReadI32();
|
public abstract int ReadI32();
|
||||||
public abstract long ReadI64();
|
public abstract long ReadI64();
|
||||||
public abstract double ReadDouble();
|
public abstract double ReadDouble();
|
||||||
public virtual string ReadString() {
|
public virtual string ReadString()
|
||||||
|
{
|
||||||
var buf = ReadBinary();
|
var buf = ReadBinary();
|
||||||
return Encoding.UTF8.GetString(buf, 0, buf.Length);
|
return Encoding.UTF8.GetString(buf, 0, buf.Length);
|
||||||
}
|
}
|
||||||
|
@ -28,26 +28,25 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Thrift.Protocol
|
namespace Thrift.Protocol
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
/**
|
/// <see cref="TProtocolDecorator"/> forwards all requests to an enclosed <see cref="TProtocol"/> instance,
|
||||||
* TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
|
/// providing a way to author concise concrete decorator subclasses. While it has
|
||||||
* providing a way to author concise concrete decorator subclasses. While it has
|
/// no abstract methods, it is marked abstract as a reminder that by itself,
|
||||||
* no abstract methods, it is marked abstract as a reminder that by itself,
|
/// it does not modify the behaviour of the enclosed <see cref="TProtocol"/>.
|
||||||
* it does not modify the behaviour of the enclosed TProtocol.
|
/// <para/>
|
||||||
*
|
/// See p.175 of Design Patterns (by Gamma et al.)
|
||||||
* See p.175 of Design Patterns (by Gamma et al.)
|
/// </summary>
|
||||||
* See TMultiplexedProtocol
|
/// <seealso cref="TMultiplexedProtocol"/>
|
||||||
*/
|
|
||||||
public abstract class TProtocolDecorator : TProtocol
|
public abstract class TProtocolDecorator : TProtocol
|
||||||
{
|
{
|
||||||
private TProtocol WrappedProtocol;
|
private TProtocol WrappedProtocol;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Encloses the specified protocol.
|
/// Encloses the specified protocol.
|
||||||
* @param protocol All operations will be forward to this protocol. Must be non-null.
|
/// </summary>
|
||||||
*/
|
/// <param name="protocol">All operations will be forward to this protocol. Must be non-null.</param>
|
||||||
public TProtocolDecorator(TProtocol protocol)
|
public TProtocolDecorator(TProtocol protocol)
|
||||||
: base( protocol.Transport)
|
: base(protocol.Transport)
|
||||||
{
|
{
|
||||||
|
|
||||||
WrappedProtocol = protocol;
|
WrappedProtocol = protocol;
|
||||||
@ -104,7 +103,7 @@ namespace Thrift.Protocol
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteListEnd()
|
public override void WriteListEnd()
|
||||||
{
|
{
|
||||||
WrappedProtocol.WriteListEnd();
|
WrappedProtocol.WriteListEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ namespace Thrift.Protocol
|
|||||||
WrappedProtocol.WriteDouble(v);
|
WrappedProtocol.WriteDouble(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WriteString(String s)
|
public override void WriteString(string s)
|
||||||
{
|
{
|
||||||
WrappedProtocol.WriteString(s);
|
WrappedProtocol.WriteString(s);
|
||||||
}
|
}
|
||||||
@ -248,7 +247,7 @@ namespace Thrift.Protocol
|
|||||||
return WrappedProtocol.ReadDouble();
|
return WrappedProtocol.ReadDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override String ReadString()
|
public override string ReadString()
|
||||||
{
|
{
|
||||||
return WrappedProtocol.ReadString();
|
return WrappedProtocol.ReadString();
|
||||||
}
|
}
|
||||||
|
@ -48,13 +48,13 @@ namespace Thrift.Protocol
|
|||||||
type_ = type;
|
type_ = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TProtocolException(int type, String message)
|
public TProtocolException(int type, string message)
|
||||||
: base(message)
|
: base(message)
|
||||||
{
|
{
|
||||||
type_ = type;
|
type_ = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TProtocolException(String message)
|
public TProtocolException(string message)
|
||||||
: base(message)
|
: base(message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,6 @@ namespace Thrift.Protocol
|
|||||||
default:
|
default:
|
||||||
throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
|
throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -28,128 +28,128 @@ using System.IO;
|
|||||||
|
|
||||||
namespace Thrift.Server
|
namespace Thrift.Server
|
||||||
{
|
{
|
||||||
public abstract class TServer
|
public abstract class TServer
|
||||||
{
|
{
|
||||||
//Attributes
|
//Attributes
|
||||||
protected TProcessorFactory processorFactory;
|
protected TProcessorFactory processorFactory;
|
||||||
protected TServerTransport serverTransport;
|
protected TServerTransport serverTransport;
|
||||||
protected TTransportFactory inputTransportFactory;
|
protected TTransportFactory inputTransportFactory;
|
||||||
protected TTransportFactory outputTransportFactory;
|
protected TTransportFactory outputTransportFactory;
|
||||||
protected TProtocolFactory inputProtocolFactory;
|
protected TProtocolFactory inputProtocolFactory;
|
||||||
protected TProtocolFactory outputProtocolFactory;
|
protected TProtocolFactory outputProtocolFactory;
|
||||||
protected TServerEventHandler serverEventHandler = null;
|
protected TServerEventHandler serverEventHandler = null;
|
||||||
|
|
||||||
//Methods
|
//Methods
|
||||||
public void setEventHandler(TServerEventHandler seh)
|
public void setEventHandler(TServerEventHandler seh)
|
||||||
{
|
{
|
||||||
serverEventHandler = seh;
|
serverEventHandler = seh;
|
||||||
}
|
}
|
||||||
public TServerEventHandler getEventHandler()
|
public TServerEventHandler getEventHandler()
|
||||||
{
|
{
|
||||||
return serverEventHandler;
|
return serverEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log delegation
|
//Log delegation
|
||||||
public delegate void LogDelegate(string str);
|
public delegate void LogDelegate(string str);
|
||||||
private LogDelegate _logDelegate;
|
private LogDelegate _logDelegate;
|
||||||
protected LogDelegate logDelegate
|
protected LogDelegate logDelegate
|
||||||
{
|
{
|
||||||
get { return _logDelegate; }
|
get { return _logDelegate; }
|
||||||
set { _logDelegate = (value != null) ? value : DefaultLogDelegate; }
|
set { _logDelegate = (value != null) ? value : DefaultLogDelegate; }
|
||||||
}
|
}
|
||||||
protected static void DefaultLogDelegate(string s)
|
protected static void DefaultLogDelegate(string s)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine(s);
|
Console.Error.WriteLine(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Construction
|
//Construction
|
||||||
public TServer(TProcessor processor,
|
public TServer(TProcessor processor,
|
||||||
TServerTransport serverTransport)
|
TServerTransport serverTransport)
|
||||||
: this(processor, serverTransport,
|
: this(processor, serverTransport,
|
||||||
new TTransportFactory(),
|
new TTransportFactory(),
|
||||||
new TTransportFactory(),
|
new TTransportFactory(),
|
||||||
new TBinaryProtocol.Factory(),
|
new TBinaryProtocol.Factory(),
|
||||||
new TBinaryProtocol.Factory(),
|
new TBinaryProtocol.Factory(),
|
||||||
DefaultLogDelegate)
|
DefaultLogDelegate)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TServer(TProcessor processor,
|
public TServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
LogDelegate logDelegate)
|
||||||
|
: this(processor,
|
||||||
|
serverTransport,
|
||||||
|
new TTransportFactory(),
|
||||||
|
new TTransportFactory(),
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
logDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory)
|
||||||
|
: this(processor,
|
||||||
|
serverTransport,
|
||||||
|
transportFactory,
|
||||||
|
transportFactory,
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory,
|
||||||
|
TProtocolFactory protocolFactory)
|
||||||
|
: this(processor,
|
||||||
|
serverTransport,
|
||||||
|
transportFactory,
|
||||||
|
transportFactory,
|
||||||
|
protocolFactory,
|
||||||
|
protocolFactory,
|
||||||
|
DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TServer(TProcessor processor,
|
||||||
TServerTransport serverTransport,
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory inputTransportFactory,
|
||||||
|
TTransportFactory outputTransportFactory,
|
||||||
|
TProtocolFactory inputProtocolFactory,
|
||||||
|
TProtocolFactory outputProtocolFactory,
|
||||||
LogDelegate logDelegate)
|
LogDelegate logDelegate)
|
||||||
: this(processor,
|
{
|
||||||
serverTransport,
|
this.processorFactory = new TSingletonProcessorFactory(processor);
|
||||||
new TTransportFactory(),
|
this.serverTransport = serverTransport;
|
||||||
new TTransportFactory(),
|
this.inputTransportFactory = inputTransportFactory;
|
||||||
new TBinaryProtocol.Factory(),
|
this.outputTransportFactory = outputTransportFactory;
|
||||||
new TBinaryProtocol.Factory(),
|
this.inputProtocolFactory = inputProtocolFactory;
|
||||||
logDelegate)
|
this.outputProtocolFactory = outputProtocolFactory;
|
||||||
{
|
this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TServer(TProcessor processor,
|
public TServer(TProcessorFactory processorFactory,
|
||||||
TServerTransport serverTransport,
|
TServerTransport serverTransport,
|
||||||
TTransportFactory transportFactory)
|
TTransportFactory inputTransportFactory,
|
||||||
: this(processor,
|
TTransportFactory outputTransportFactory,
|
||||||
serverTransport,
|
TProtocolFactory inputProtocolFactory,
|
||||||
transportFactory,
|
TProtocolFactory outputProtocolFactory,
|
||||||
transportFactory,
|
LogDelegate logDelegate)
|
||||||
new TBinaryProtocol.Factory(),
|
{
|
||||||
new TBinaryProtocol.Factory(),
|
this.processorFactory = processorFactory;
|
||||||
DefaultLogDelegate)
|
this.serverTransport = serverTransport;
|
||||||
{
|
this.inputTransportFactory = inputTransportFactory;
|
||||||
}
|
this.outputTransportFactory = outputTransportFactory;
|
||||||
|
this.inputProtocolFactory = inputProtocolFactory;
|
||||||
|
this.outputProtocolFactory = outputProtocolFactory;
|
||||||
|
this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
public TServer(TProcessor processor,
|
//Abstract Interface
|
||||||
TServerTransport serverTransport,
|
public abstract void Serve();
|
||||||
TTransportFactory transportFactory,
|
public abstract void Stop();
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: this(processor,
|
|
||||||
serverTransport,
|
|
||||||
transportFactory,
|
|
||||||
transportFactory,
|
|
||||||
protocolFactory,
|
|
||||||
protocolFactory,
|
|
||||||
DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory inputTransportFactory,
|
|
||||||
TTransportFactory outputTransportFactory,
|
|
||||||
TProtocolFactory inputProtocolFactory,
|
|
||||||
TProtocolFactory outputProtocolFactory,
|
|
||||||
LogDelegate logDelegate)
|
|
||||||
{
|
|
||||||
this.processorFactory = new TSingletonProcessorFactory(processor);
|
|
||||||
this.serverTransport = serverTransport;
|
|
||||||
this.inputTransportFactory = inputTransportFactory;
|
|
||||||
this.outputTransportFactory = outputTransportFactory;
|
|
||||||
this.inputProtocolFactory = inputProtocolFactory;
|
|
||||||
this.outputProtocolFactory = outputProtocolFactory;
|
|
||||||
this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory inputTransportFactory,
|
|
||||||
TTransportFactory outputTransportFactory,
|
|
||||||
TProtocolFactory inputProtocolFactory,
|
|
||||||
TProtocolFactory outputProtocolFactory,
|
|
||||||
LogDelegate logDelegate)
|
|
||||||
{
|
|
||||||
this.processorFactory = processorFactory;
|
|
||||||
this.serverTransport = serverTransport;
|
|
||||||
this.inputTransportFactory = inputTransportFactory;
|
|
||||||
this.outputTransportFactory = outputTransportFactory;
|
|
||||||
this.inputProtocolFactory = inputProtocolFactory;
|
|
||||||
this.outputProtocolFactory = outputProtocolFactory;
|
|
||||||
this.logDelegate = (logDelegate != null) ? logDelegate : DefaultLogDelegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Abstract Interface
|
|
||||||
public abstract void Serve();
|
|
||||||
public abstract void Stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,26 +25,29 @@ using System;
|
|||||||
|
|
||||||
namespace Thrift.Server
|
namespace Thrift.Server
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Interface implemented by server users to handle events from the server
|
|
||||||
/// </summary>
|
|
||||||
public interface TServerEventHandler
|
|
||||||
{
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called before the server begins */
|
/// Interface implemented by server users to handle events from the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void preServe();
|
public interface TServerEventHandler
|
||||||
/// <summary>
|
{
|
||||||
/// Called when a new client has connected and is about to being processing */
|
/// <summary>
|
||||||
/// </summary>
|
/// Called before the server begins.
|
||||||
Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
|
/// </summary>
|
||||||
/// <summary>
|
void preServe();
|
||||||
/// Called when a client has finished request-handling to delete server context */
|
|
||||||
/// </summary>
|
/// <summary>
|
||||||
void deleteContext(Object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
|
/// Called when a new client has connected and is about to being processing.
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Called when a client is about to call the processor */
|
object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
|
||||||
/// </summary>
|
|
||||||
void processContext(Object serverContext, Thrift.Transport.TTransport transport);
|
/// <summary>
|
||||||
};
|
/// Called when a client has finished request-handling to delete server context.
|
||||||
|
/// </summary>
|
||||||
|
void deleteContext(object serverContext, Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a client is about to call the processor.
|
||||||
|
/// </summary>
|
||||||
|
void processContext(object serverContext, Thrift.Transport.TTransport transport);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -27,154 +27,154 @@ using Thrift.Protocol;
|
|||||||
|
|
||||||
namespace Thrift.Server
|
namespace Thrift.Server
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Simple single-threaded server for testing
|
/// Simple single-threaded server for testing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TSimpleServer : TServer
|
public class TSimpleServer : TServer
|
||||||
{
|
|
||||||
private bool stop = false;
|
|
||||||
|
|
||||||
public TSimpleServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport)
|
|
||||||
: base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
|
|
||||||
{
|
{
|
||||||
}
|
private bool stop = false;
|
||||||
|
|
||||||
public TSimpleServer(TProcessor processor,
|
public TSimpleServer(TProcessor processor,
|
||||||
TServerTransport serverTransport,
|
TServerTransport serverTransport)
|
||||||
LogDelegate logDel)
|
: base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
|
||||||
: base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), logDel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSimpleServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory)
|
|
||||||
: base(processor,
|
|
||||||
serverTransport,
|
|
||||||
transportFactory,
|
|
||||||
transportFactory,
|
|
||||||
new TBinaryProtocol.Factory(),
|
|
||||||
new TBinaryProtocol.Factory(),
|
|
||||||
DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSimpleServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: base(processor,
|
|
||||||
serverTransport,
|
|
||||||
transportFactory,
|
|
||||||
transportFactory,
|
|
||||||
protocolFactory,
|
|
||||||
protocolFactory,
|
|
||||||
DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TSimpleServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: base(processorFactory,
|
|
||||||
serverTransport,
|
|
||||||
transportFactory,
|
|
||||||
transportFactory,
|
|
||||||
protocolFactory,
|
|
||||||
protocolFactory,
|
|
||||||
DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serve()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
serverTransport.Listen();
|
|
||||||
}
|
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
logDelegate(ttx.ToString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fire the preServe server event when server is up but before any client connections
|
|
||||||
if (serverEventHandler != null)
|
|
||||||
serverEventHandler.preServe();
|
|
||||||
|
|
||||||
while (!stop)
|
|
||||||
{
|
|
||||||
TProcessor processor = null;
|
|
||||||
TTransport client = null;
|
|
||||||
TTransport inputTransport = null;
|
|
||||||
TTransport outputTransport = null;
|
|
||||||
TProtocol inputProtocol = null;
|
|
||||||
TProtocol outputProtocol = null;
|
|
||||||
Object connectionContext = null;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
using (client = serverTransport.Accept())
|
}
|
||||||
{
|
|
||||||
processor = processorFactory.GetProcessor(client);
|
public TSimpleServer(TProcessor processor,
|
||||||
if (client != null)
|
TServerTransport serverTransport,
|
||||||
|
LogDelegate logDel)
|
||||||
|
: base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), logDel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TSimpleServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory)
|
||||||
|
: base(processor,
|
||||||
|
serverTransport,
|
||||||
|
transportFactory,
|
||||||
|
transportFactory,
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
new TBinaryProtocol.Factory(),
|
||||||
|
DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TSimpleServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory,
|
||||||
|
TProtocolFactory protocolFactory)
|
||||||
|
: base(processor,
|
||||||
|
serverTransport,
|
||||||
|
transportFactory,
|
||||||
|
transportFactory,
|
||||||
|
protocolFactory,
|
||||||
|
protocolFactory,
|
||||||
|
DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TSimpleServer(TProcessorFactory processorFactory,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory,
|
||||||
|
TProtocolFactory protocolFactory)
|
||||||
|
: base(processorFactory,
|
||||||
|
serverTransport,
|
||||||
|
transportFactory,
|
||||||
|
transportFactory,
|
||||||
|
protocolFactory,
|
||||||
|
protocolFactory,
|
||||||
|
DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Serve()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
using (inputTransport = inputTransportFactory.GetTransport(client))
|
serverTransport.Listen();
|
||||||
{
|
}
|
||||||
using (outputTransport = outputTransportFactory.GetTransport(client))
|
catch (TTransportException ttx)
|
||||||
{
|
{
|
||||||
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
logDelegate(ttx.ToString());
|
||||||
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
return;
|
||||||
|
}
|
||||||
//Recover event handler (if any) and fire createContext server event when a client connects
|
|
||||||
if (serverEventHandler != null)
|
//Fire the preServe server event when server is up but before any client connections
|
||||||
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.preServe();
|
||||||
//Process client requests until client disconnects
|
|
||||||
while (!stop)
|
while (!stop)
|
||||||
{
|
{
|
||||||
if (!inputTransport.Peek())
|
TProcessor processor = null;
|
||||||
break;
|
TTransport client = null;
|
||||||
|
TTransport inputTransport = null;
|
||||||
//Fire processContext server event
|
TTransport outputTransport = null;
|
||||||
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
TProtocol inputProtocol = null;
|
||||||
//That is to say it may be many minutes between the event firing and the client request
|
TProtocol outputProtocol = null;
|
||||||
//actually arriving or the client may hang up without ever makeing a request.
|
object connectionContext = null;
|
||||||
if (serverEventHandler != null)
|
try
|
||||||
serverEventHandler.processContext(connectionContext, inputTransport);
|
{
|
||||||
//Process client request (blocks until transport is readable)
|
using (client = serverTransport.Accept())
|
||||||
if (!processor.Process(inputProtocol, outputProtocol))
|
{
|
||||||
break;
|
processor = processorFactory.GetProcessor(client);
|
||||||
}
|
if (client != null)
|
||||||
}
|
{
|
||||||
}
|
using (inputTransport = inputTransportFactory.GetTransport(client))
|
||||||
|
{
|
||||||
|
using (outputTransport = outputTransportFactory.GetTransport(client))
|
||||||
|
{
|
||||||
|
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
||||||
|
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
||||||
|
|
||||||
|
//Recover event handler (if any) and fire createContext server event when a client connects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
||||||
|
|
||||||
|
//Process client requests until client disconnects
|
||||||
|
while (!stop)
|
||||||
|
{
|
||||||
|
if (!inputTransport.Peek())
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Fire processContext server event
|
||||||
|
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
||||||
|
//That is to say it may be many minutes between the event firing and the client request
|
||||||
|
//actually arriving or the client may hang up without ever makeing a request.
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.processContext(connectionContext, inputTransport);
|
||||||
|
//Process client request (blocks until transport is readable)
|
||||||
|
if (!processor.Process(inputProtocol, outputProtocol))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (TTransportException ttx)
|
||||||
|
{
|
||||||
|
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
||||||
|
{
|
||||||
|
logDelegate(ttx.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception x)
|
||||||
|
{
|
||||||
|
//Unexpected
|
||||||
|
logDelegate(x.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire deleteContext server event after client disconnects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
|
||||||
{
|
|
||||||
logDelegate(ttx.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception x)
|
|
||||||
{
|
|
||||||
//Unexpected
|
|
||||||
logDelegate(x.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Fire deleteContext server event after client disconnects
|
public override void Stop()
|
||||||
if (serverEventHandler != null)
|
{
|
||||||
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
stop = true;
|
||||||
}
|
serverTransport.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Stop()
|
|
||||||
{
|
|
||||||
stop = true;
|
|
||||||
serverTransport.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -28,268 +28,268 @@ using Thrift.Transport;
|
|||||||
|
|
||||||
namespace Thrift.Server
|
namespace Thrift.Server
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Server that uses C# built-in ThreadPool to spawn threads when handling requests
|
|
||||||
/// </summary>
|
|
||||||
public class TThreadPoolServer : TServer
|
|
||||||
{
|
|
||||||
private const int DEFAULT_MIN_THREADS = -1; // use .NET ThreadPool defaults
|
|
||||||
private const int DEFAULT_MAX_THREADS = -1; // use .NET ThreadPool defaults
|
|
||||||
private volatile bool stop = false;
|
|
||||||
|
|
||||||
public struct Configuration
|
|
||||||
{
|
|
||||||
public int MinWorkerThreads;
|
|
||||||
public int MaxWorkerThreads;
|
|
||||||
public int MinIOThreads;
|
|
||||||
public int MaxIOThreads;
|
|
||||||
|
|
||||||
public Configuration(int min = DEFAULT_MIN_THREADS, int max = DEFAULT_MAX_THREADS)
|
|
||||||
{
|
|
||||||
MinWorkerThreads = min;
|
|
||||||
MaxWorkerThreads = max;
|
|
||||||
MinIOThreads = min;
|
|
||||||
MaxIOThreads = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Configuration(int minWork, int maxWork, int minIO, int maxIO)
|
|
||||||
{
|
|
||||||
MinWorkerThreads = minWork;
|
|
||||||
MaxWorkerThreads = maxWork;
|
|
||||||
MinIOThreads = minIO;
|
|
||||||
MaxIOThreads = maxIO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
new TTransportFactory(), new TTransportFactory(),
|
|
||||||
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
|
||||||
new Configuration(), DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
new TTransportFactory(), new TTransportFactory(),
|
|
||||||
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
|
||||||
new Configuration(), logDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
transportFactory, transportFactory,
|
|
||||||
protocolFactory, protocolFactory,
|
|
||||||
new Configuration(), DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: this(processorFactory, serverTransport,
|
|
||||||
transportFactory, transportFactory,
|
|
||||||
protocolFactory, protocolFactory,
|
|
||||||
new Configuration(), DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory inputTransportFactory,
|
|
||||||
TTransportFactory outputTransportFactory,
|
|
||||||
TProtocolFactory inputProtocolFactory,
|
|
||||||
TProtocolFactory outputProtocolFactory,
|
|
||||||
int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel)
|
|
||||||
: this(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
|
||||||
inputProtocolFactory, outputProtocolFactory,
|
|
||||||
new Configuration(minThreadPoolThreads, maxThreadPoolThreads),
|
|
||||||
logDel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadPoolServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory inputTransportFactory,
|
|
||||||
TTransportFactory outputTransportFactory,
|
|
||||||
TProtocolFactory inputProtocolFactory,
|
|
||||||
TProtocolFactory outputProtocolFactory,
|
|
||||||
Configuration threadConfig,
|
|
||||||
LogDelegate logDel)
|
|
||||||
: base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
|
||||||
inputProtocolFactory, outputProtocolFactory, logDel)
|
|
||||||
{
|
|
||||||
lock (typeof(TThreadPoolServer))
|
|
||||||
{
|
|
||||||
if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0))
|
|
||||||
{
|
|
||||||
int work, comm;
|
|
||||||
ThreadPool.GetMaxThreads(out work, out comm);
|
|
||||||
if (threadConfig.MaxWorkerThreads > 0)
|
|
||||||
work = threadConfig.MaxWorkerThreads;
|
|
||||||
if (threadConfig.MaxIOThreads > 0)
|
|
||||||
comm = threadConfig.MaxIOThreads;
|
|
||||||
if (!ThreadPool.SetMaxThreads(work, comm))
|
|
||||||
throw new Exception("Error: could not SetMaxThreads in ThreadPool");
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0))
|
|
||||||
{
|
|
||||||
int work, comm;
|
|
||||||
ThreadPool.GetMinThreads(out work, out comm);
|
|
||||||
if (threadConfig.MinWorkerThreads > 0)
|
|
||||||
work = threadConfig.MinWorkerThreads;
|
|
||||||
if (threadConfig.MinIOThreads > 0)
|
|
||||||
comm = threadConfig.MinIOThreads;
|
|
||||||
if (!ThreadPool.SetMinThreads(work, comm))
|
|
||||||
throw new Exception("Error: could not SetMinThreads in ThreadPool");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use new ThreadPool thread for each new client connection
|
/// Server that uses C# built-in ThreadPool to spawn threads when handling requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void Serve()
|
public class TThreadPoolServer : TServer
|
||||||
{
|
{
|
||||||
try
|
private const int DEFAULT_MIN_THREADS = -1; // use .NET ThreadPool defaults
|
||||||
{
|
private const int DEFAULT_MAX_THREADS = -1; // use .NET ThreadPool defaults
|
||||||
serverTransport.Listen();
|
private volatile bool stop = false;
|
||||||
}
|
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
logDelegate("Error, could not listen on ServerTransport: " + ttx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fire the preServe server event when server is up but before any client connections
|
public struct Configuration
|
||||||
if (serverEventHandler != null)
|
|
||||||
serverEventHandler.preServe();
|
|
||||||
|
|
||||||
while (!stop)
|
|
||||||
{
|
|
||||||
int failureCount = 0;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
TTransport client = serverTransport.Accept();
|
public int MinWorkerThreads;
|
||||||
ThreadPool.QueueUserWorkItem(this.Execute, client);
|
public int MaxWorkerThreads;
|
||||||
|
public int MinIOThreads;
|
||||||
|
public int MaxIOThreads;
|
||||||
|
|
||||||
|
public Configuration(int min = DEFAULT_MIN_THREADS, int max = DEFAULT_MAX_THREADS)
|
||||||
|
{
|
||||||
|
MinWorkerThreads = min;
|
||||||
|
MaxWorkerThreads = max;
|
||||||
|
MinIOThreads = min;
|
||||||
|
MaxIOThreads = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Configuration(int minWork, int maxWork, int minIO, int maxIO)
|
||||||
|
{
|
||||||
|
MinWorkerThreads = minWork;
|
||||||
|
MaxWorkerThreads = maxWork;
|
||||||
|
MinIOThreads = minIO;
|
||||||
|
MaxIOThreads = maxIO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
|
||||||
{
|
|
||||||
++failureCount;
|
|
||||||
logDelegate(ttx.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport)
|
||||||
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
|
new TTransportFactory(), new TTransportFactory(),
|
||||||
|
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
||||||
|
new Configuration(), DefaultLogDelegate)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (stop)
|
public TThreadPoolServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
|
||||||
{
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
try
|
new TTransportFactory(), new TTransportFactory(),
|
||||||
|
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
||||||
|
new Configuration(), logDelegate)
|
||||||
{
|
{
|
||||||
serverTransport.Close();
|
|
||||||
}
|
}
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
logDelegate("TServerTransport failed on close: " + ttx.Message);
|
|
||||||
}
|
|
||||||
stop = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
public TThreadPoolServer(TProcessor processor,
|
||||||
/// Loops on processing a client forever
|
TServerTransport serverTransport,
|
||||||
/// threadContext will be a TTransport instance
|
TTransportFactory transportFactory,
|
||||||
/// </summary>
|
TProtocolFactory protocolFactory)
|
||||||
/// <param name="threadContext"></param>
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
private void Execute(Object threadContext)
|
transportFactory, transportFactory,
|
||||||
{
|
protocolFactory, protocolFactory,
|
||||||
using( TTransport client = (TTransport)threadContext)
|
new Configuration(), DefaultLogDelegate)
|
||||||
{
|
|
||||||
TProcessor processor = processorFactory.GetProcessor(client, this);
|
|
||||||
TTransport inputTransport = null;
|
|
||||||
TTransport outputTransport = null;
|
|
||||||
TProtocol inputProtocol = null;
|
|
||||||
TProtocol outputProtocol = null;
|
|
||||||
Object connectionContext = null;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
try
|
}
|
||||||
{
|
|
||||||
inputTransport = inputTransportFactory.GetTransport(client);
|
public TThreadPoolServer(TProcessorFactory processorFactory,
|
||||||
outputTransport = outputTransportFactory.GetTransport(client);
|
TServerTransport serverTransport,
|
||||||
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
TTransportFactory transportFactory,
|
||||||
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
TProtocolFactory protocolFactory)
|
||||||
|
: this(processorFactory, serverTransport,
|
||||||
//Recover event handler (if any) and fire createContext server event when a client connects
|
transportFactory, transportFactory,
|
||||||
|
protocolFactory, protocolFactory,
|
||||||
|
new Configuration(), DefaultLogDelegate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TThreadPoolServer(TProcessorFactory processorFactory,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory inputTransportFactory,
|
||||||
|
TTransportFactory outputTransportFactory,
|
||||||
|
TProtocolFactory inputProtocolFactory,
|
||||||
|
TProtocolFactory outputProtocolFactory,
|
||||||
|
int minThreadPoolThreads, int maxThreadPoolThreads, LogDelegate logDel)
|
||||||
|
: this(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
||||||
|
inputProtocolFactory, outputProtocolFactory,
|
||||||
|
new Configuration(minThreadPoolThreads, maxThreadPoolThreads),
|
||||||
|
logDel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TThreadPoolServer(TProcessorFactory processorFactory,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory inputTransportFactory,
|
||||||
|
TTransportFactory outputTransportFactory,
|
||||||
|
TProtocolFactory inputProtocolFactory,
|
||||||
|
TProtocolFactory outputProtocolFactory,
|
||||||
|
Configuration threadConfig,
|
||||||
|
LogDelegate logDel)
|
||||||
|
: base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
||||||
|
inputProtocolFactory, outputProtocolFactory, logDel)
|
||||||
|
{
|
||||||
|
lock (typeof(TThreadPoolServer))
|
||||||
|
{
|
||||||
|
if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0))
|
||||||
|
{
|
||||||
|
int work, comm;
|
||||||
|
ThreadPool.GetMaxThreads(out work, out comm);
|
||||||
|
if (threadConfig.MaxWorkerThreads > 0)
|
||||||
|
work = threadConfig.MaxWorkerThreads;
|
||||||
|
if (threadConfig.MaxIOThreads > 0)
|
||||||
|
comm = threadConfig.MaxIOThreads;
|
||||||
|
if (!ThreadPool.SetMaxThreads(work, comm))
|
||||||
|
throw new Exception("Error: could not SetMaxThreads in ThreadPool");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0))
|
||||||
|
{
|
||||||
|
int work, comm;
|
||||||
|
ThreadPool.GetMinThreads(out work, out comm);
|
||||||
|
if (threadConfig.MinWorkerThreads > 0)
|
||||||
|
work = threadConfig.MinWorkerThreads;
|
||||||
|
if (threadConfig.MinIOThreads > 0)
|
||||||
|
comm = threadConfig.MinIOThreads;
|
||||||
|
if (!ThreadPool.SetMinThreads(work, comm))
|
||||||
|
throw new Exception("Error: could not SetMinThreads in ThreadPool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use new ThreadPool thread for each new client connection.
|
||||||
|
/// </summary>
|
||||||
|
public override void Serve()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serverTransport.Listen();
|
||||||
|
}
|
||||||
|
catch (TTransportException ttx)
|
||||||
|
{
|
||||||
|
logDelegate("Error, could not listen on ServerTransport: " + ttx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire the preServe server event when server is up but before any client connections
|
||||||
if (serverEventHandler != null)
|
if (serverEventHandler != null)
|
||||||
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
serverEventHandler.preServe();
|
||||||
|
|
||||||
//Process client requests until client disconnects
|
|
||||||
while (!stop)
|
while (!stop)
|
||||||
{
|
{
|
||||||
if (!inputTransport.Peek())
|
int failureCount = 0;
|
||||||
break;
|
try
|
||||||
|
{
|
||||||
//Fire processContext server event
|
TTransport client = serverTransport.Accept();
|
||||||
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
ThreadPool.QueueUserWorkItem(this.Execute, client);
|
||||||
//That is to say it may be many minutes between the event firing and the client request
|
}
|
||||||
//actually arriving or the client may hang up without ever makeing a request.
|
catch (TTransportException ttx)
|
||||||
if (serverEventHandler != null)
|
{
|
||||||
serverEventHandler.processContext(connectionContext, inputTransport);
|
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
||||||
//Process client request (blocks until transport is readable)
|
{
|
||||||
if (!processor.Process(inputProtocol, outputProtocol))
|
++failureCount;
|
||||||
break;
|
logDelegate(ttx.ToString());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (TTransportException)
|
|
||||||
{
|
|
||||||
//Usually a client disconnect, expected
|
|
||||||
}
|
|
||||||
catch (Exception x)
|
|
||||||
{
|
|
||||||
//Unexpected
|
|
||||||
logDelegate("Error: " + x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fire deleteContext server event after client disconnects
|
|
||||||
if (serverEventHandler != null)
|
|
||||||
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
|
||||||
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//Close transports
|
|
||||||
if (inputTransport != null)
|
|
||||||
inputTransport.Close();
|
|
||||||
if (outputTransport != null)
|
|
||||||
outputTransport.Close();
|
|
||||||
|
|
||||||
// disposable stuff should be disposed
|
|
||||||
if( inputProtocol != null)
|
|
||||||
inputProtocol.Dispose();
|
|
||||||
if( outputProtocol != null)
|
|
||||||
outputProtocol.Dispose();
|
|
||||||
if( inputTransport != null)
|
|
||||||
inputTransport.Dispose();
|
|
||||||
if( outputTransport != null)
|
|
||||||
outputTransport.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Stop()
|
}
|
||||||
{
|
}
|
||||||
stop = true;
|
|
||||||
serverTransport.Close();
|
if (stop)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
serverTransport.Close();
|
||||||
|
}
|
||||||
|
catch (TTransportException ttx)
|
||||||
|
{
|
||||||
|
logDelegate("TServerTransport failed on close: " + ttx.Message);
|
||||||
|
}
|
||||||
|
stop = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loops on processing a client forever
|
||||||
|
/// threadContext will be a TTransport instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="threadContext"></param>
|
||||||
|
private void Execute(object threadContext)
|
||||||
|
{
|
||||||
|
using (TTransport client = (TTransport)threadContext)
|
||||||
|
{
|
||||||
|
TProcessor processor = processorFactory.GetProcessor(client, this);
|
||||||
|
TTransport inputTransport = null;
|
||||||
|
TTransport outputTransport = null;
|
||||||
|
TProtocol inputProtocol = null;
|
||||||
|
TProtocol outputProtocol = null;
|
||||||
|
object connectionContext = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inputTransport = inputTransportFactory.GetTransport(client);
|
||||||
|
outputTransport = outputTransportFactory.GetTransport(client);
|
||||||
|
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
||||||
|
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
||||||
|
|
||||||
|
//Recover event handler (if any) and fire createContext server event when a client connects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
||||||
|
|
||||||
|
//Process client requests until client disconnects
|
||||||
|
while (!stop)
|
||||||
|
{
|
||||||
|
if (!inputTransport.Peek())
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Fire processContext server event
|
||||||
|
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
||||||
|
//That is to say it may be many minutes between the event firing and the client request
|
||||||
|
//actually arriving or the client may hang up without ever makeing a request.
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.processContext(connectionContext, inputTransport);
|
||||||
|
//Process client request (blocks until transport is readable)
|
||||||
|
if (!processor.Process(inputProtocol, outputProtocol))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (TTransportException)
|
||||||
|
{
|
||||||
|
//Usually a client disconnect, expected
|
||||||
|
}
|
||||||
|
catch (Exception x)
|
||||||
|
{
|
||||||
|
//Unexpected
|
||||||
|
logDelegate("Error: " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire deleteContext server event after client disconnects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//Close transports
|
||||||
|
if (inputTransport != null)
|
||||||
|
inputTransport.Close();
|
||||||
|
if (outputTransport != null)
|
||||||
|
outputTransport.Close();
|
||||||
|
|
||||||
|
// disposable stuff should be disposed
|
||||||
|
if (inputProtocol != null)
|
||||||
|
inputProtocol.Dispose();
|
||||||
|
if (outputProtocol != null)
|
||||||
|
outputProtocol.Dispose();
|
||||||
|
if (inputTransport != null)
|
||||||
|
inputTransport.Dispose();
|
||||||
|
if (outputTransport != null)
|
||||||
|
outputTransport.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Stop()
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
serverTransport.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,258 +26,257 @@ using Thrift.Transport;
|
|||||||
|
|
||||||
namespace Thrift.Server
|
namespace Thrift.Server
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Server that uses C# threads (as opposed to the ThreadPool) when handling requests
|
|
||||||
/// </summary>
|
|
||||||
public class TThreadedServer : TServer
|
|
||||||
{
|
|
||||||
private const int DEFAULT_MAX_THREADS = 100;
|
|
||||||
private volatile bool stop = false;
|
|
||||||
private readonly int maxThreads;
|
|
||||||
|
|
||||||
private Queue<TTransport> clientQueue;
|
|
||||||
private THashSet<Thread> clientThreads;
|
|
||||||
private object clientLock;
|
|
||||||
private Thread workerThread;
|
|
||||||
|
|
||||||
public int ClientThreadsCount {
|
|
||||||
get { return clientThreads.Count; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadedServer(TProcessor processor, TServerTransport serverTransport)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
new TTransportFactory(), new TTransportFactory(),
|
|
||||||
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
|
||||||
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadedServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
new TTransportFactory(), new TTransportFactory(),
|
|
||||||
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
|
||||||
DEFAULT_MAX_THREADS, logDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public TThreadedServer(TProcessor processor,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
|
||||||
transportFactory, transportFactory,
|
|
||||||
protocolFactory, protocolFactory,
|
|
||||||
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public TThreadedServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory transportFactory,
|
|
||||||
TProtocolFactory protocolFactory)
|
|
||||||
: this(processorFactory, serverTransport,
|
|
||||||
transportFactory, transportFactory,
|
|
||||||
protocolFactory, protocolFactory,
|
|
||||||
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public TThreadedServer(TProcessorFactory processorFactory,
|
|
||||||
TServerTransport serverTransport,
|
|
||||||
TTransportFactory inputTransportFactory,
|
|
||||||
TTransportFactory outputTransportFactory,
|
|
||||||
TProtocolFactory inputProtocolFactory,
|
|
||||||
TProtocolFactory outputProtocolFactory,
|
|
||||||
int maxThreads, LogDelegate logDel)
|
|
||||||
: base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
|
||||||
inputProtocolFactory, outputProtocolFactory, logDel)
|
|
||||||
{
|
|
||||||
this.maxThreads = maxThreads;
|
|
||||||
clientQueue = new Queue<TTransport>();
|
|
||||||
clientLock = new object();
|
|
||||||
clientThreads = new THashSet<Thread>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use new Thread for each new client connection. block until numConnections < maxThreads
|
/// Server that uses C# threads (as opposed to the ThreadPool) when handling requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override void Serve()
|
public class TThreadedServer : TServer
|
||||||
{
|
{
|
||||||
try
|
private const int DEFAULT_MAX_THREADS = 100;
|
||||||
{
|
private volatile bool stop = false;
|
||||||
//start worker thread
|
private readonly int maxThreads;
|
||||||
workerThread = new Thread(new ThreadStart(Execute));
|
|
||||||
workerThread.Start();
|
|
||||||
serverTransport.Listen();
|
|
||||||
}
|
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
logDelegate("Error, could not listen on ServerTransport: " + ttx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fire the preServe server event when server is up but before any client connections
|
private Queue<TTransport> clientQueue;
|
||||||
if (serverEventHandler != null)
|
private THashSet<Thread> clientThreads;
|
||||||
serverEventHandler.preServe();
|
private object clientLock;
|
||||||
|
private Thread workerThread;
|
||||||
|
|
||||||
while (!stop)
|
public int ClientThreadsCount
|
||||||
{
|
|
||||||
int failureCount = 0;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
TTransport client = serverTransport.Accept();
|
get { return clientThreads.Count; }
|
||||||
lock (clientLock)
|
|
||||||
{
|
|
||||||
clientQueue.Enqueue(client);
|
|
||||||
Monitor.Pulse(clientLock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (TTransportException ttx)
|
|
||||||
{
|
|
||||||
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
|
||||||
{
|
|
||||||
++failureCount;
|
|
||||||
logDelegate(ttx.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public TThreadedServer(TProcessor processor, TServerTransport serverTransport)
|
||||||
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
|
new TTransportFactory(), new TTransportFactory(),
|
||||||
|
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
||||||
|
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (stop)
|
public TThreadedServer(TProcessor processor, TServerTransport serverTransport, LogDelegate logDelegate)
|
||||||
{
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
try
|
new TTransportFactory(), new TTransportFactory(),
|
||||||
|
new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(),
|
||||||
|
DEFAULT_MAX_THREADS, logDelegate)
|
||||||
{
|
{
|
||||||
serverTransport.Close();
|
|
||||||
}
|
}
|
||||||
catch (TTransportException ttx)
|
|
||||||
|
|
||||||
|
public TThreadedServer(TProcessor processor,
|
||||||
|
TServerTransport serverTransport,
|
||||||
|
TTransportFactory transportFactory,
|
||||||
|
TProtocolFactory protocolFactory)
|
||||||
|
: this(new TSingletonProcessorFactory(processor), serverTransport,
|
||||||
|
transportFactory, transportFactory,
|
||||||
|
protocolFactory, protocolFactory,
|
||||||
|
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
||||||
{
|
{
|
||||||
logDelegate("TServeTransport failed on close: " + ttx.Message);
|
|
||||||
}
|
}
|
||||||
stop = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
public TThreadedServer(TProcessorFactory processorFactory,
|
||||||
/// Loops on processing a client forever
|
TServerTransport serverTransport,
|
||||||
/// threadContext will be a TTransport instance
|
TTransportFactory transportFactory,
|
||||||
/// </summary>
|
TProtocolFactory protocolFactory)
|
||||||
/// <param name="threadContext"></param>
|
: this(processorFactory, serverTransport,
|
||||||
private void Execute()
|
transportFactory, transportFactory,
|
||||||
{
|
protocolFactory, protocolFactory,
|
||||||
while (!stop)
|
DEFAULT_MAX_THREADS, DefaultLogDelegate)
|
||||||
{
|
|
||||||
TTransport client;
|
|
||||||
Thread t;
|
|
||||||
lock (clientLock)
|
|
||||||
{
|
{
|
||||||
//don't dequeue if too many connections
|
|
||||||
while (clientThreads.Count >= maxThreads)
|
|
||||||
{
|
|
||||||
Monitor.Wait(clientLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (clientQueue.Count == 0)
|
|
||||||
{
|
|
||||||
Monitor.Wait(clientLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
client = clientQueue.Dequeue();
|
|
||||||
t = new Thread(new ParameterizedThreadStart(ClientWorker));
|
|
||||||
clientThreads.Add(t);
|
|
||||||
}
|
}
|
||||||
//start processing requests from client on new thread
|
public TThreadedServer(TProcessorFactory processorFactory,
|
||||||
t.Start(client);
|
TServerTransport serverTransport,
|
||||||
}
|
TTransportFactory inputTransportFactory,
|
||||||
}
|
TTransportFactory outputTransportFactory,
|
||||||
|
TProtocolFactory inputProtocolFactory,
|
||||||
private void ClientWorker(Object context)
|
TProtocolFactory outputProtocolFactory,
|
||||||
{
|
int maxThreads, LogDelegate logDel)
|
||||||
using( TTransport client = (TTransport)context)
|
: base(processorFactory, serverTransport, inputTransportFactory, outputTransportFactory,
|
||||||
{
|
inputProtocolFactory, outputProtocolFactory, logDel)
|
||||||
TProcessor processor = processorFactory.GetProcessor(client);
|
|
||||||
TTransport inputTransport = null;
|
|
||||||
TTransport outputTransport = null;
|
|
||||||
TProtocol inputProtocol = null;
|
|
||||||
TProtocol outputProtocol = null;
|
|
||||||
Object connectionContext = null;
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
try
|
this.maxThreads = maxThreads;
|
||||||
{
|
clientQueue = new Queue<TTransport>();
|
||||||
inputTransport = inputTransportFactory.GetTransport(client);
|
clientLock = new object();
|
||||||
outputTransport = outputTransportFactory.GetTransport(client);
|
clientThreads = new THashSet<Thread>();
|
||||||
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
}
|
||||||
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
|
||||||
|
/// <summary>
|
||||||
//Recover event handler (if any) and fire createContext server event when a client connects
|
/// Use new Thread for each new client connection. block until numConnections < maxThreads.
|
||||||
|
/// </summary>
|
||||||
|
public override void Serve()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//start worker thread
|
||||||
|
workerThread = new Thread(new ThreadStart(Execute));
|
||||||
|
workerThread.Start();
|
||||||
|
serverTransport.Listen();
|
||||||
|
}
|
||||||
|
catch (TTransportException ttx)
|
||||||
|
{
|
||||||
|
logDelegate("Error, could not listen on ServerTransport: " + ttx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire the preServe server event when server is up but before any client connections
|
||||||
if (serverEventHandler != null)
|
if (serverEventHandler != null)
|
||||||
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
serverEventHandler.preServe();
|
||||||
|
|
||||||
//Process client requests until client disconnects
|
|
||||||
while (!stop)
|
while (!stop)
|
||||||
{
|
{
|
||||||
if (!inputTransport.Peek())
|
int failureCount = 0;
|
||||||
break;
|
try
|
||||||
|
{
|
||||||
//Fire processContext server event
|
TTransport client = serverTransport.Accept();
|
||||||
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
lock (clientLock)
|
||||||
//That is to say it may be many minutes between the event firing and the client request
|
{
|
||||||
//actually arriving or the client may hang up without ever makeing a request.
|
clientQueue.Enqueue(client);
|
||||||
if (serverEventHandler != null)
|
Monitor.Pulse(clientLock);
|
||||||
serverEventHandler.processContext(connectionContext, inputTransport);
|
}
|
||||||
//Process client request (blocks until transport is readable)
|
}
|
||||||
if (!processor.Process(inputProtocol, outputProtocol))
|
catch (TTransportException ttx)
|
||||||
break;
|
{
|
||||||
|
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
|
||||||
|
{
|
||||||
|
++failureCount;
|
||||||
|
logDelegate(ttx.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (TTransportException)
|
|
||||||
{
|
|
||||||
//Usually a client disconnect, expected
|
|
||||||
}
|
|
||||||
catch (Exception x)
|
|
||||||
{
|
|
||||||
//Unexpected
|
|
||||||
logDelegate("Error: " + x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Fire deleteContext server event after client disconnects
|
|
||||||
if (serverEventHandler != null)
|
|
||||||
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
|
||||||
|
|
||||||
lock (clientLock)
|
|
||||||
{
|
|
||||||
clientThreads.Remove(Thread.CurrentThread);
|
|
||||||
Monitor.Pulse(clientLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if (stop)
|
||||||
finally
|
{
|
||||||
{
|
try
|
||||||
//Close transports
|
{
|
||||||
if (inputTransport != null)
|
serverTransport.Close();
|
||||||
inputTransport.Close();
|
}
|
||||||
if (outputTransport != null)
|
catch (TTransportException ttx)
|
||||||
outputTransport.Close();
|
{
|
||||||
|
logDelegate("TServeTransport failed on close: " + ttx.Message);
|
||||||
// disposable stuff should be disposed
|
}
|
||||||
if (inputProtocol != null)
|
stop = false;
|
||||||
inputProtocol.Dispose();
|
}
|
||||||
if (outputProtocol != null)
|
|
||||||
outputProtocol.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Stop()
|
/// <summary>
|
||||||
{
|
/// Loops on processing a client forever
|
||||||
stop = true;
|
/// </summary>
|
||||||
serverTransport.Close();
|
private void Execute()
|
||||||
//clean up all the threads myself
|
{
|
||||||
workerThread.Abort();
|
while (!stop)
|
||||||
foreach (Thread t in clientThreads)
|
{
|
||||||
{
|
TTransport client;
|
||||||
t.Abort();
|
Thread t;
|
||||||
}
|
lock (clientLock)
|
||||||
|
{
|
||||||
|
//don't dequeue if too many connections
|
||||||
|
while (clientThreads.Count >= maxThreads)
|
||||||
|
{
|
||||||
|
Monitor.Wait(clientLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (clientQueue.Count == 0)
|
||||||
|
{
|
||||||
|
Monitor.Wait(clientLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
client = clientQueue.Dequeue();
|
||||||
|
t = new Thread(new ParameterizedThreadStart(ClientWorker));
|
||||||
|
clientThreads.Add(t);
|
||||||
|
}
|
||||||
|
//start processing requests from client on new thread
|
||||||
|
t.Start(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClientWorker(object context)
|
||||||
|
{
|
||||||
|
using (TTransport client = (TTransport)context)
|
||||||
|
{
|
||||||
|
TProcessor processor = processorFactory.GetProcessor(client);
|
||||||
|
TTransport inputTransport = null;
|
||||||
|
TTransport outputTransport = null;
|
||||||
|
TProtocol inputProtocol = null;
|
||||||
|
TProtocol outputProtocol = null;
|
||||||
|
object connectionContext = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inputTransport = inputTransportFactory.GetTransport(client);
|
||||||
|
outputTransport = outputTransportFactory.GetTransport(client);
|
||||||
|
inputProtocol = inputProtocolFactory.GetProtocol(inputTransport);
|
||||||
|
outputProtocol = outputProtocolFactory.GetProtocol(outputTransport);
|
||||||
|
|
||||||
|
//Recover event handler (if any) and fire createContext server event when a client connects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
|
||||||
|
|
||||||
|
//Process client requests until client disconnects
|
||||||
|
while (!stop)
|
||||||
|
{
|
||||||
|
if (!inputTransport.Peek())
|
||||||
|
break;
|
||||||
|
|
||||||
|
//Fire processContext server event
|
||||||
|
//N.B. This is the pattern implemented in C++ and the event fires provisionally.
|
||||||
|
//That is to say it may be many minutes between the event firing and the client request
|
||||||
|
//actually arriving or the client may hang up without ever makeing a request.
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.processContext(connectionContext, inputTransport);
|
||||||
|
//Process client request (blocks until transport is readable)
|
||||||
|
if (!processor.Process(inputProtocol, outputProtocol))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (TTransportException)
|
||||||
|
{
|
||||||
|
//Usually a client disconnect, expected
|
||||||
|
}
|
||||||
|
catch (Exception x)
|
||||||
|
{
|
||||||
|
//Unexpected
|
||||||
|
logDelegate("Error: " + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Fire deleteContext server event after client disconnects
|
||||||
|
if (serverEventHandler != null)
|
||||||
|
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
|
||||||
|
|
||||||
|
lock (clientLock)
|
||||||
|
{
|
||||||
|
clientThreads.Remove(Thread.CurrentThread);
|
||||||
|
Monitor.Pulse(clientLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//Close transports
|
||||||
|
if (inputTransport != null)
|
||||||
|
inputTransport.Close();
|
||||||
|
if (outputTransport != null)
|
||||||
|
outputTransport.Close();
|
||||||
|
|
||||||
|
// disposable stuff should be disposed
|
||||||
|
if (inputProtocol != null)
|
||||||
|
inputProtocol.Dispose();
|
||||||
|
if (outputProtocol != null)
|
||||||
|
outputProtocol.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Stop()
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
serverTransport.Close();
|
||||||
|
//clean up all the threads myself
|
||||||
|
workerThread.Abort();
|
||||||
|
foreach (Thread t in clientThreads)
|
||||||
|
{
|
||||||
|
t.Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ namespace Thrift
|
|||||||
|
|
||||||
oprot.WriteStructBegin(struc);
|
oprot.WriteStructBegin(struc);
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(Message))
|
if (!string.IsNullOrEmpty(Message))
|
||||||
{
|
{
|
||||||
field.Name = "message";
|
field.Name = "message";
|
||||||
field.Type = TType.String;
|
field.Type = TType.String;
|
||||||
|
@ -31,7 +31,7 @@ namespace Thrift
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TException( string message)
|
public TException(string message)
|
||||||
: base(message)
|
: base(message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace Thrift
|
|||||||
|
|
||||||
public TProcessor GetProcessor(TTransport trans, TServer server = null)
|
public TProcessor GetProcessor(TTransport trans, TServer server = null)
|
||||||
{
|
{
|
||||||
H handler = (H) Activator.CreateInstance(typeof(H), handlerArgs);
|
H handler = (H)Activator.CreateInstance(typeof(H), handlerArgs);
|
||||||
|
|
||||||
TControllingHandler handlerServerRef = handler as TControllingHandler;
|
TControllingHandler handlerServerRef = handler as TControllingHandler;
|
||||||
if (handlerServerRef != null)
|
if (handlerServerRef != null)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -154,11 +154,11 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
if(inputBuffer != null)
|
if (inputBuffer != null)
|
||||||
inputBuffer.Dispose();
|
inputBuffer.Dispose();
|
||||||
if(outputBuffer != null)
|
if (outputBuffer != null)
|
||||||
outputBuffer.Dispose();
|
outputBuffer.Dispose();
|
||||||
if(transport != null)
|
if (transport != null)
|
||||||
transport.Dispose();
|
transport.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,8 +116,8 @@ namespace Thrift.Transport
|
|||||||
byte[] buf = writeBuffer.GetBuffer();
|
byte[] buf = writeBuffer.GetBuffer();
|
||||||
int len = (int)writeBuffer.Length;
|
int len = (int)writeBuffer.Length;
|
||||||
int data_len = len - HeaderSize;
|
int data_len = len - HeaderSize;
|
||||||
if ( data_len < 0 )
|
if (data_len < 0)
|
||||||
throw new System.InvalidOperationException (); // logic error actually
|
throw new System.InvalidOperationException(); // logic error actually
|
||||||
|
|
||||||
// Inject message header into the reserved buffer space
|
// Inject message header into the reserved buffer space
|
||||||
EncodeFrameSize(data_len, buf);
|
EncodeFrameSize(data_len, buf);
|
||||||
@ -130,7 +130,7 @@ namespace Thrift.Transport
|
|||||||
transport.Flush();
|
transport.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitWriteBuffer ()
|
private void InitWriteBuffer()
|
||||||
{
|
{
|
||||||
// Reserve space for message header to be put right before sending it out
|
// Reserve space for message header to be put right before sending it out
|
||||||
writeBuffer.SetLength(HeaderSize);
|
writeBuffer.SetLength(HeaderSize);
|
||||||
@ -150,7 +150,7 @@ namespace Thrift.Transport
|
|||||||
return
|
return
|
||||||
((buf[0] & 0xff) << 24) |
|
((buf[0] & 0xff) << 24) |
|
||||||
((buf[1] & 0xff) << 16) |
|
((buf[1] & 0xff) << 16) |
|
||||||
((buf[2] & 0xff) << 8) |
|
((buf[2] & 0xff) << 8) |
|
||||||
((buf[3] & 0xff));
|
((buf[3] & 0xff));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,11 +171,11 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
if(readBuffer != null)
|
if (readBuffer != null)
|
||||||
readBuffer.Dispose();
|
readBuffer.Dispose();
|
||||||
if(writeBuffer != null)
|
if (writeBuffer != null)
|
||||||
writeBuffer.Dispose();
|
writeBuffer.Dispose();
|
||||||
if(transport != null)
|
if (transport != null)
|
||||||
transport.Dispose();
|
transport.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ using System.IO.Compression;
|
|||||||
|
|
||||||
namespace Thrift.Transport
|
namespace Thrift.Transport
|
||||||
{
|
{
|
||||||
|
|
||||||
public class THttpClient : TTransport, IDisposable
|
public class THttpClient : TTransport, IDisposable
|
||||||
{
|
{
|
||||||
private readonly Uri uri;
|
private readonly Uri uri;
|
||||||
@ -43,7 +42,7 @@ namespace Thrift.Transport
|
|||||||
|
|
||||||
private int readTimeout = 30000;
|
private int readTimeout = 30000;
|
||||||
|
|
||||||
private IDictionary<String, String> customHeaders = new Dictionary<string, string>();
|
private IDictionary<string, string> customHeaders = new Dictionary<string, string>();
|
||||||
|
|
||||||
#if !SILVERLIGHT
|
#if !SILVERLIGHT
|
||||||
private IWebProxy proxy = WebRequest.DefaultWebProxy;
|
private IWebProxy proxy = WebRequest.DefaultWebProxy;
|
||||||
@ -64,7 +63,7 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
connectTimeout = value;
|
connectTimeout = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +75,7 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDictionary<String, String> CustomHeaders
|
public IDictionary<string, string> CustomHeaders
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -325,7 +324,7 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var flushAsyncResult = (FlushAsyncResult) asyncResult;
|
var flushAsyncResult = (FlushAsyncResult)asyncResult;
|
||||||
|
|
||||||
if (!flushAsyncResult.IsCompleted)
|
if (!flushAsyncResult.IsCompleted)
|
||||||
{
|
{
|
||||||
@ -338,7 +337,8 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
throw flushAsyncResult.AsyncException;
|
throw flushAsyncResult.AsyncException;
|
||||||
}
|
}
|
||||||
} finally
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
outputStream = new MemoryStream();
|
outputStream = new MemoryStream();
|
||||||
}
|
}
|
||||||
@ -387,9 +387,9 @@ namespace Thrift.Transport
|
|||||||
private volatile Boolean _isCompleted;
|
private volatile Boolean _isCompleted;
|
||||||
private ManualResetEvent _evt;
|
private ManualResetEvent _evt;
|
||||||
private readonly AsyncCallback _cbMethod;
|
private readonly AsyncCallback _cbMethod;
|
||||||
private readonly Object _state;
|
private readonly object _state;
|
||||||
|
|
||||||
public FlushAsyncResult(AsyncCallback cbMethod, Object state)
|
public FlushAsyncResult(AsyncCallback cbMethod, object state)
|
||||||
{
|
{
|
||||||
_cbMethod = cbMethod;
|
_cbMethod = cbMethod;
|
||||||
_state = state;
|
_state = state;
|
||||||
@ -415,7 +415,7 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
get { return _isCompleted; }
|
get { return _isCompleted; }
|
||||||
}
|
}
|
||||||
private readonly Object _locker = new Object();
|
private readonly object _locker = new object();
|
||||||
private ManualResetEvent GetEvtHandle()
|
private ManualResetEvent GetEvtHandle()
|
||||||
{
|
{
|
||||||
lock (_locker)
|
lock (_locker)
|
||||||
@ -452,7 +452,7 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region " IDisposable Support "
|
#region " IDisposable Support "
|
||||||
private bool _IsDisposed;
|
private bool _IsDisposed;
|
||||||
|
|
||||||
// IDisposable
|
// IDisposable
|
||||||
@ -470,6 +470,6 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
_IsDisposed = true;
|
_IsDisposed = true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,45 +22,56 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Thrift.Protocol;
|
using Thrift.Protocol;
|
||||||
|
|
||||||
namespace Thrift.Transport {
|
namespace Thrift.Transport
|
||||||
public class TMemoryBuffer : TTransport {
|
{
|
||||||
|
public class TMemoryBuffer : TTransport
|
||||||
|
{
|
||||||
|
|
||||||
private readonly MemoryStream byteStream;
|
private readonly MemoryStream byteStream;
|
||||||
|
|
||||||
public TMemoryBuffer() {
|
public TMemoryBuffer()
|
||||||
|
{
|
||||||
byteStream = new MemoryStream();
|
byteStream = new MemoryStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TMemoryBuffer(byte[] buf) {
|
public TMemoryBuffer(byte[] buf)
|
||||||
|
{
|
||||||
byteStream = new MemoryStream(buf);
|
byteStream = new MemoryStream(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Open() {
|
public override void Open()
|
||||||
|
{
|
||||||
/** do nothing **/
|
/** do nothing **/
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close() {
|
public override void Close()
|
||||||
|
{
|
||||||
/** do nothing **/
|
/** do nothing **/
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Read(byte[] buf, int off, int len) {
|
public override int Read(byte[] buf, int off, int len)
|
||||||
|
{
|
||||||
return byteStream.Read(buf, off, len);
|
return byteStream.Read(buf, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(byte[] buf, int off, int len) {
|
public override void Write(byte[] buf, int off, int len)
|
||||||
|
{
|
||||||
byteStream.Write(buf, off, len);
|
byteStream.Write(buf, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetBuffer() {
|
public byte[] GetBuffer()
|
||||||
|
{
|
||||||
return byteStream.ToArray();
|
return byteStream.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool IsOpen {
|
public override bool IsOpen
|
||||||
|
{
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] Serialize(TAbstractBase s) {
|
public static byte[] Serialize(TAbstractBase s)
|
||||||
|
{
|
||||||
var t = new TMemoryBuffer();
|
var t = new TMemoryBuffer();
|
||||||
var p = new TBinaryProtocol(t);
|
var p = new TBinaryProtocol(t);
|
||||||
|
|
||||||
@ -69,26 +80,33 @@ namespace Thrift.Transport {
|
|||||||
return t.GetBuffer();
|
return t.GetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T DeSerialize<T>(byte[] buf) where T : TAbstractBase {
|
public static T DeSerialize<T>(byte[] buf) where T : TAbstractBase
|
||||||
|
{
|
||||||
var trans = new TMemoryBuffer(buf);
|
var trans = new TMemoryBuffer(buf);
|
||||||
var p = new TBinaryProtocol(trans);
|
var p = new TBinaryProtocol(trans);
|
||||||
if (typeof (TBase).IsAssignableFrom(typeof (T))) {
|
if (typeof(TBase).IsAssignableFrom(typeof(T)))
|
||||||
var method = typeof (T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
|
{
|
||||||
|
var method = typeof(T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
|
||||||
var t = Activator.CreateInstance<T>();
|
var t = Activator.CreateInstance<T>();
|
||||||
method.Invoke(t, new object[] {p});
|
method.Invoke(t, new object[] { p });
|
||||||
return t;
|
return t;
|
||||||
} else {
|
}
|
||||||
var method = typeof (T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
|
else
|
||||||
return (T) method.Invoke(null, new object[] {p});
|
{
|
||||||
|
var method = typeof(T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
|
||||||
|
return (T)method.Invoke(null, new object[] { p });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _IsDisposed;
|
private bool _IsDisposed;
|
||||||
|
|
||||||
// IDisposable
|
// IDisposable
|
||||||
protected override void Dispose(bool disposing) {
|
protected override void Dispose(bool disposing)
|
||||||
if (!_IsDisposed) {
|
{
|
||||||
if (disposing) {
|
if (!_IsDisposed)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
if (byteStream != null)
|
if (byteStream != null)
|
||||||
byteStream.Dispose();
|
byteStream.Dispose();
|
||||||
}
|
}
|
||||||
@ -96,4 +114,4 @@ namespace Thrift.Transport {
|
|||||||
_IsDisposed = true;
|
_IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,4 +108,4 @@ namespace Thrift.Transport
|
|||||||
client.Dispose();
|
client.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,150 +27,150 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace Thrift.Transport
|
namespace Thrift.Transport
|
||||||
{
|
{
|
||||||
public class TServerSocket : TServerTransport
|
public class TServerSocket : TServerTransport
|
||||||
{
|
{
|
||||||
/**
|
/// <summary>
|
||||||
* Underlying server with socket
|
/// Underlying server with socket.
|
||||||
*/
|
/// </summary>
|
||||||
private TcpListener server = null;
|
private TcpListener server = null;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Port to listen on
|
/// Port to listen on.
|
||||||
*/
|
/// </summary>
|
||||||
private int port = 0;
|
private int port = 0;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Timeout for client sockets from accept
|
/// Timeout for client sockets from accept.
|
||||||
*/
|
/// </summary>
|
||||||
private int clientTimeout = 0;
|
private int clientTimeout = 0;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Whether or not to wrap new TSocket connections in buffers
|
/// Whether or not to wrap new TSocket connections in buffers.
|
||||||
*/
|
/// </summary>
|
||||||
private bool useBufferedSockets = false;
|
private bool useBufferedSockets = false;
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Creates a server socket from underlying socket object
|
/// Creates a server socket from underlying socket object.
|
||||||
*/
|
/// </summary>
|
||||||
public TServerSocket(TcpListener listener)
|
public TServerSocket(TcpListener listener)
|
||||||
:this(listener, 0)
|
: this(listener, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Creates a server socket from underlying socket object
|
/// Creates a server socket from underlying socket object.
|
||||||
*/
|
/// </summary>
|
||||||
public TServerSocket(TcpListener listener, int clientTimeout)
|
public TServerSocket(TcpListener listener, int clientTimeout)
|
||||||
{
|
{
|
||||||
this.server = listener;
|
this.server = listener;
|
||||||
this.clientTimeout = clientTimeout;
|
this.clientTimeout = clientTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Creates just a port listening server socket
|
/// Creates just a port listening server socket.
|
||||||
*/
|
/// </summary>
|
||||||
public TServerSocket(int port)
|
public TServerSocket(int port)
|
||||||
: this(port, 0)
|
: this(port, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// <summary>
|
||||||
* Creates just a port listening server socket
|
/// Creates just a port listening server socket.
|
||||||
*/
|
/// </summary>
|
||||||
public TServerSocket(int port, int clientTimeout)
|
public TServerSocket(int port, int clientTimeout)
|
||||||
:this(port, clientTimeout, false)
|
: this(port, clientTimeout, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
|
public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
|
||||||
{
|
{
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.clientTimeout = clientTimeout;
|
this.clientTimeout = clientTimeout;
|
||||||
this.useBufferedSockets = useBufferedSockets;
|
this.useBufferedSockets = useBufferedSockets;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Make server socket
|
// Make server socket
|
||||||
this.server = TSocketVersionizer.CreateTcpListener(this.port);
|
this.server = TSocketVersionizer.CreateTcpListener(this.port);
|
||||||
this.server.Server.NoDelay = true;
|
this.server.Server.NoDelay = true;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
server = null;
|
server = null;
|
||||||
throw new TTransportException("Could not create ServerSocket on port " + this.port + ".");
|
throw new TTransportException("Could not create ServerSocket on port " + this.port + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Listen()
|
public override void Listen()
|
||||||
{
|
{
|
||||||
// Make sure not to block on accept
|
// Make sure not to block on accept
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
server.Start();
|
server.Start();
|
||||||
}
|
}
|
||||||
catch (SocketException sx)
|
catch (SocketException sx)
|
||||||
{
|
{
|
||||||
throw new TTransportException("Could not accept on listening socket: " + sx.Message);
|
throw new TTransportException("Could not accept on listening socket: " + sx.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TTransport AcceptImpl()
|
protected override TTransport AcceptImpl()
|
||||||
{
|
{
|
||||||
if (server == null)
|
if (server == null)
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
|
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
TSocket result2 = null;
|
TSocket result2 = null;
|
||||||
TcpClient result = server.AcceptTcpClient();
|
TcpClient result = server.AcceptTcpClient();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result2 = new TSocket(result);
|
result2 = new TSocket(result);
|
||||||
result2.Timeout = clientTimeout;
|
result2.Timeout = clientTimeout;
|
||||||
if (useBufferedSockets)
|
if (useBufferedSockets)
|
||||||
{
|
{
|
||||||
TBufferedTransport result3 = new TBufferedTransport(result2);
|
TBufferedTransport result3 = new TBufferedTransport(result2);
|
||||||
return result3;
|
return result3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return result2;
|
return result2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.Exception)
|
catch (System.Exception)
|
||||||
{
|
{
|
||||||
// If a TSocket was successfully created, then let
|
// If a TSocket was successfully created, then let
|
||||||
// it do proper cleanup of the TcpClient object.
|
// it do proper cleanup of the TcpClient object.
|
||||||
if (result2 != null)
|
if (result2 != null)
|
||||||
result2.Dispose();
|
result2.Dispose();
|
||||||
else // Otherwise, clean it up ourselves.
|
else // Otherwise, clean it up ourselves.
|
||||||
((IDisposable)result).Dispose();
|
((IDisposable)result).Dispose();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new TTransportException(ex.ToString());
|
throw new TTransportException(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
if (server != null)
|
if (server != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new TTransportException("WARNING: Could not close server socket: " + ex);
|
throw new TTransportException("WARNING: Could not close server socket: " + ex);
|
||||||
}
|
}
|
||||||
server = null;
|
server = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,11 @@ namespace Thrift.Transport
|
|||||||
public TTransport Accept()
|
public TTransport Accept()
|
||||||
{
|
{
|
||||||
TTransport transport = AcceptImpl();
|
TTransport transport = AcceptImpl();
|
||||||
if (transport == null) {
|
if (transport == null)
|
||||||
throw new TTransportException("accept() may not return NULL");
|
{
|
||||||
|
throw new TTransportException("accept() may not return NULL");
|
||||||
}
|
}
|
||||||
return transport;
|
return transport;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ namespace Thrift.Transport
|
|||||||
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(host))
|
if (string.IsNullOrEmpty(host))
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
||||||
}
|
}
|
||||||
@ -282,9 +282,9 @@ namespace Thrift.Transport
|
|||||||
private volatile Boolean _isCompleted;
|
private volatile Boolean _isCompleted;
|
||||||
private ManualResetEvent _evt;
|
private ManualResetEvent _evt;
|
||||||
private readonly AsyncCallback _cbMethod;
|
private readonly AsyncCallback _cbMethod;
|
||||||
private readonly Object _state;
|
private readonly object _state;
|
||||||
|
|
||||||
public FlushAsyncResult(AsyncCallback cbMethod, Object state)
|
public FlushAsyncResult(AsyncCallback cbMethod, object state)
|
||||||
{
|
{
|
||||||
_cbMethod = cbMethod;
|
_cbMethod = cbMethod;
|
||||||
_state = state;
|
_state = state;
|
||||||
@ -314,7 +314,7 @@ namespace Thrift.Transport
|
|||||||
get { return _isCompleted; }
|
get { return _isCompleted; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Object _locker = new Object();
|
private readonly object _locker = new object();
|
||||||
|
|
||||||
private ManualResetEvent GetEvtHandle()
|
private ManualResetEvent GetEvtHandle()
|
||||||
{
|
{
|
||||||
@ -362,7 +362,7 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region " IDisposable Support "
|
#region " IDisposable Support "
|
||||||
private bool _IsDisposed;
|
private bool _IsDisposed;
|
||||||
|
|
||||||
// IDisposable
|
// IDisposable
|
||||||
@ -385,7 +385,7 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
_IsDisposed = true;
|
_IsDisposed = true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,216 +26,220 @@ using System.Net.Sockets;
|
|||||||
|
|
||||||
namespace Thrift.Transport
|
namespace Thrift.Transport
|
||||||
{
|
{
|
||||||
public class TSocket : TStreamTransport
|
public class TSocket : TStreamTransport
|
||||||
{
|
{
|
||||||
private TcpClient client = null;
|
private TcpClient client = null;
|
||||||
private string host = null;
|
private string host = null;
|
||||||
private int port = 0;
|
private int port = 0;
|
||||||
private int timeout = 0;
|
private int timeout = 0;
|
||||||
|
|
||||||
public TSocket(TcpClient client)
|
public TSocket(TcpClient client)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
if (IsOpen)
|
if (IsOpen)
|
||||||
{
|
{
|
||||||
inputStream = client.GetStream();
|
inputStream = client.GetStream();
|
||||||
outputStream = client.GetStream();
|
outputStream = client.GetStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSocket(string host, int port)
|
public TSocket(string host, int port)
|
||||||
: this(host, port, 0)
|
: this(host, port, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TSocket(string host, int port, int timeout)
|
public TSocket(string host, int port, int timeout)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.timeout = timeout;
|
this.timeout = timeout;
|
||||||
|
|
||||||
InitSocket();
|
InitSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitSocket()
|
private void InitSocket()
|
||||||
{
|
{
|
||||||
this.client = TSocketVersionizer.CreateTcpClient();
|
this.client = TSocketVersionizer.CreateTcpClient();
|
||||||
this.client.ReceiveTimeout = client.SendTimeout = timeout;
|
this.client.ReceiveTimeout = client.SendTimeout = timeout;
|
||||||
this.client.Client.NoDelay = true;
|
this.client.Client.NoDelay = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Timeout
|
public int Timeout
|
||||||
{
|
{
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
client.ReceiveTimeout = client.SendTimeout = timeout = value;
|
client.ReceiveTimeout = client.SendTimeout = timeout = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TcpClient TcpClient
|
public TcpClient TcpClient
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Host
|
public string Host
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Port
|
public int Port
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsOpen
|
public override bool IsOpen
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return client.Connected;
|
return client.Connected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Open()
|
public override void Open()
|
||||||
{
|
{
|
||||||
if (IsOpen)
|
if (IsOpen)
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(host))
|
if (string.IsNullOrEmpty(host))
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port <= 0)
|
if (port <= 0)
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
|
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
InitSocket();
|
InitSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( timeout == 0) // no timeout -> infinite
|
if (timeout == 0) // no timeout -> infinite
|
||||||
{
|
{
|
||||||
client.Connect(host, port);
|
client.Connect(host, port);
|
||||||
}
|
}
|
||||||
else // we have a timeout -> use it
|
else // we have a timeout -> use it
|
||||||
{
|
{
|
||||||
ConnectHelper hlp = new ConnectHelper(client);
|
ConnectHelper hlp = new ConnectHelper(client);
|
||||||
IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
|
IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
|
||||||
bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
|
bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
|
||||||
if (!bConnected)
|
if (!bConnected)
|
||||||
{
|
{
|
||||||
lock (hlp.Mutex)
|
lock (hlp.Mutex)
|
||||||
{
|
{
|
||||||
if( hlp.CallbackDone)
|
if (hlp.CallbackDone)
|
||||||
{
|
{
|
||||||
asyncres.AsyncWaitHandle.Close();
|
asyncres.AsyncWaitHandle.Close();
|
||||||
client.Close();
|
client.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hlp.DoCleanup = true;
|
hlp.DoCleanup = true;
|
||||||
client = null;
|
client = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
|
throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputStream = client.GetStream();
|
inputStream = client.GetStream();
|
||||||
outputStream = client.GetStream();
|
outputStream = client.GetStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ConnectCallback(IAsyncResult asyncres)
|
static void ConnectCallback(IAsyncResult asyncres)
|
||||||
{
|
{
|
||||||
ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
|
ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
|
||||||
lock (hlp.Mutex)
|
lock (hlp.Mutex)
|
||||||
{
|
{
|
||||||
hlp.CallbackDone = true;
|
hlp.CallbackDone = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if( hlp.Client.Client != null)
|
if (hlp.Client.Client != null)
|
||||||
hlp.Client.EndConnect(asyncres);
|
hlp.Client.EndConnect(asyncres);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// catch that away
|
// catch that away
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hlp.DoCleanup)
|
if (hlp.DoCleanup)
|
||||||
{
|
{
|
||||||
try {
|
try
|
||||||
asyncres.AsyncWaitHandle.Close();
|
{
|
||||||
} catch (Exception) {}
|
asyncres.AsyncWaitHandle.Close();
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
|
||||||
try {
|
try
|
||||||
if (hlp.Client is IDisposable)
|
{
|
||||||
((IDisposable)hlp.Client).Dispose();
|
if (hlp.Client is IDisposable)
|
||||||
} catch (Exception) {}
|
((IDisposable)hlp.Client).Dispose();
|
||||||
hlp.Client = null;
|
}
|
||||||
}
|
catch (Exception) { }
|
||||||
}
|
hlp.Client = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ConnectHelper
|
private class ConnectHelper
|
||||||
{
|
{
|
||||||
public object Mutex = new object();
|
public object Mutex = new object();
|
||||||
public bool DoCleanup = false;
|
public bool DoCleanup = false;
|
||||||
public bool CallbackDone = false;
|
public bool CallbackDone = false;
|
||||||
public TcpClient Client;
|
public TcpClient Client;
|
||||||
public ConnectHelper(TcpClient client)
|
public ConnectHelper(TcpClient client)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
base.Close();
|
base.Close();
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
client.Close();
|
client.Close();
|
||||||
client = null;
|
client = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region " IDisposable Support "
|
#region " IDisposable Support "
|
||||||
private bool _IsDisposed;
|
private bool _IsDisposed;
|
||||||
|
|
||||||
// IDisposable
|
// IDisposable
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (!_IsDisposed)
|
if (!_IsDisposed)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (client != null)
|
||||||
((IDisposable)client).Dispose();
|
((IDisposable)client).Dispose();
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_IsDisposed = true;
|
_IsDisposed = true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
using System;
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Contains some contributions under the Thrift Software License.
|
||||||
|
* Please see doc/old-thrift-license.txt in the Thrift distribution for
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
@ -10,46 +33,46 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Thrift.Transport
|
namespace Thrift.Transport
|
||||||
{
|
{
|
||||||
/**
|
/// <summary>
|
||||||
* PropertyInfo for the DualMode property of the System.Net.Sockets.Socket class. Used to determine if the sockets are capable of
|
/// PropertyInfo for the DualMode property of the System.Net.Sockets.Socket class. Used to determine if the sockets are capable of
|
||||||
* automatic IPv4 and IPv6 handling. If DualMode is present the sockets automatically handle IPv4 and IPv6 connections.
|
/// automatic IPv4 and IPv6 handling. If DualMode is present the sockets automatically handle IPv4 and IPv6 connections.
|
||||||
* If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
|
/// If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
|
||||||
*/
|
/// </summary>
|
||||||
internal static class TSocketVersionizer
|
internal static class TSocketVersionizer
|
||||||
{
|
{
|
||||||
/*
|
/// <summary>
|
||||||
* Creates a TcpClient according to the capabilitites of the used framework
|
/// Creates a TcpClient according to the capabilitites of the used framework
|
||||||
*/
|
/// </summary>
|
||||||
internal static TcpClient CreateTcpClient()
|
internal static TcpClient CreateTcpClient()
|
||||||
{
|
{
|
||||||
TcpClient client = null;
|
TcpClient client = null;
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
client = new TcpClient(AddressFamily.InterNetworkV6);
|
client = new TcpClient(AddressFamily.InterNetworkV6);
|
||||||
client.Client.DualMode = true;
|
client.Client.DualMode = true;
|
||||||
#else
|
#else
|
||||||
client = new TcpClient(AddressFamily.InterNetwork);
|
client = new TcpClient(AddressFamily.InterNetwork);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// <summary>
|
||||||
* Creates a TcpListener according to the capabilitites of the used framework
|
/// Creates a TcpListener according to the capabilitites of the used framework.
|
||||||
*/
|
/// </summary>
|
||||||
internal static TcpListener CreateTcpListener(Int32 port)
|
internal static TcpListener CreateTcpListener(Int32 port)
|
||||||
{
|
{
|
||||||
TcpListener listener = null;
|
TcpListener listener = null;
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
|
listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
|
||||||
listener.Server.DualMode = true;
|
listener.Server.DualMode = true;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
listener = new TcpListener(System.Net.IPAddress.Any, port);
|
listener = new TcpListener(System.Net.IPAddress.Any, port);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,24 +105,24 @@ namespace Thrift.Transport
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region " IDisposable Support "
|
#region " IDisposable Support "
|
||||||
private bool _IsDisposed;
|
private bool _IsDisposed;
|
||||||
|
|
||||||
// IDisposable
|
// IDisposable
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
{
|
|
||||||
if (!_IsDisposed)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
{
|
||||||
if (InputStream != null)
|
if (!_IsDisposed)
|
||||||
InputStream.Dispose();
|
{
|
||||||
if (OutputStream != null)
|
if (disposing)
|
||||||
OutputStream.Dispose();
|
{
|
||||||
|
if (InputStream != null)
|
||||||
|
InputStream.Dispose();
|
||||||
|
if (OutputStream != null)
|
||||||
|
OutputStream.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_IsDisposed = true;
|
||||||
}
|
}
|
||||||
}
|
#endregion
|
||||||
_IsDisposed = true;
|
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ namespace Thrift.Transport
|
|||||||
/// <param name="port">The port where the server runs.</param>
|
/// <param name="port">The port where the server runs.</param>
|
||||||
/// <param name="certificate">The certificate object.</param>
|
/// <param name="certificate">The certificate object.</param>
|
||||||
public TTLSServerSocket(int port, X509Certificate2 certificate)
|
public TTLSServerSocket(int port, X509Certificate2 certificate)
|
||||||
: this(port, 0, certificate)
|
: this(port, 0, certificate)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ namespace Thrift.Transport
|
|||||||
/// <param name="sender">The sender-object.</param>
|
/// <param name="sender">The sender-object.</param>
|
||||||
/// <param name="certificate">The used certificate.</param>
|
/// <param name="certificate">The used certificate.</param>
|
||||||
/// <param name="chain">The certificate chain.</param>
|
/// <param name="chain">The certificate chain.</param>
|
||||||
/// <param name="sslPolicyErrors">An enum, which lists all the errors from the .NET certificate check.</param>
|
/// <param name="sslValidationErrors">An enum, which lists all the errors from the .NET certificate check.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors)
|
private bool DefaultCertificateValidator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslValidationErrors)
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@ namespace Thrift.Transport
|
|||||||
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(host))
|
if (string.IsNullOrEmpty(host))
|
||||||
{
|
{
|
||||||
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
|
||||||
}
|
}
|
||||||
@ -307,7 +307,7 @@ namespace Thrift.Transport
|
|||||||
{
|
{
|
||||||
RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
|
RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
|
||||||
|
|
||||||
if( this.localCertificateSelectionCallback != null)
|
if (this.localCertificateSelectionCallback != null)
|
||||||
{
|
{
|
||||||
this.secureStream = new SslStream(
|
this.secureStream = new SslStream(
|
||||||
this.client.GetStream(),
|
this.client.GetStream(),
|
||||||
@ -335,7 +335,7 @@ namespace Thrift.Transport
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Client authentication
|
// Client authentication
|
||||||
X509CertificateCollection certs = certificate != null ? new X509CertificateCollection { certificate } : new X509CertificateCollection();
|
X509CertificateCollection certs = certificate != null ? new X509CertificateCollection { certificate } : new X509CertificateCollection();
|
||||||
this.secureStream.AuthenticateAsClient(host, certs, sslProtocols, true);
|
this.secureStream.AuthenticateAsClient(host, certs, sslProtocols, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ namespace Thrift.Transport
|
|||||||
if (bytes == 0)
|
if (bytes == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
catch( IOException)
|
catch (IOException)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ namespace Thrift.Transport
|
|||||||
|
|
||||||
public virtual void Write(byte[] buf)
|
public virtual void Write(byte[] buf)
|
||||||
{
|
{
|
||||||
Write (buf, 0, buf.Length);
|
Write(buf, 0, buf.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void Write(byte[] buf, int off, int len);
|
public abstract void Write(byte[] buf, int off, int len);
|
||||||
|
@ -26,7 +26,7 @@ using System;
|
|||||||
namespace Thrift.Transport
|
namespace Thrift.Transport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// From Mark Slee & Aditya Agarwal of Facebook:
|
/// From Mark Slee & Aditya Agarwal of Facebook:
|
||||||
/// Factory class used to create wrapped instance of Transports.
|
/// Factory class used to create wrapped instance of Transports.
|
||||||
/// This is used primarily in servers, which get Transports from
|
/// This is used primarily in servers, which get Transports from
|
||||||
/// a ServerTransport and then may want to mutate them (i.e. create
|
/// a ServerTransport and then may want to mutate them (i.e. create
|
||||||
|
Loading…
Reference in New Issue
Block a user