THRIFT-4535: XML docs; code cleanup (tabs->spaces; String->string)

Client: C#
Patch: Christian Weiss

This closes #1524
This commit is contained in:
Christian Weiss 2018-03-30 21:26:04 +02:00 committed by Jens Geyer
parent d4fb364d30
commit 8fb719efb1
36 changed files with 1653 additions and 1606 deletions

View File

@ -79,7 +79,7 @@ namespace Thrift.Collections
}
int hashcode = 0;
foreach (Object obj in enumerable)
foreach (object obj in enumerable)
{
IEnumerable enum2 = obj as IEnumerable;
int objHash = enum2 == null ? obj.GetHashCode () : GetHashCode (enum2);
@ -91,4 +91,4 @@ namespace Thrift.Collections
return hashcode;
}
}
}
}

View File

@ -21,9 +21,9 @@ namespace Thrift.Protocol
{
public interface TAbstractBase
{
///
/// Writes the objects out to the protocol
///
/// <summary>
/// Writes the objects out to the protocol.
/// </summary>
void Write(TProtocol tProtocol);
}
}

View File

@ -21,9 +21,9 @@ namespace Thrift.Protocol
{
public interface TBase : TAbstractBase
{
///
/// <summary>
/// Reads the TObject from the given input protocol.
///
/// </summary>
void Read(TProtocol tProtocol);
}
}

View File

@ -36,29 +36,28 @@ namespace Thrift.Protocol
protected bool strictWrite_ = true;
#region BinaryProtocol Factory
/**
* Factory
*/
public class Factory : TProtocolFactory {
protected bool strictRead_ = false;
protected bool strictWrite_ = true;
public class Factory : TProtocolFactory
{
protected bool strictRead_ = false;
protected bool strictWrite_ = true;
public Factory()
: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()
: this(false, true)
{
}
}
public Factory(bool strictRead, bool strictWrite)
{
strictRead_ = strictRead;
strictWrite_ = strictWrite;
}
public TProtocol GetProtocol(TTransport trans)
{
return new TBinaryProtocol(trans, strictRead_, strictWrite_);
}
}
#endregion
@ -68,7 +67,7 @@ namespace Thrift.Protocol
}
public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
:base(trans)
: base(trans)
{
strictRead_ = strictRead;
strictWrite_ = strictWrite;
@ -345,16 +344,17 @@ namespace Thrift.Protocol
public override long ReadI64()
{
ReadAll(i64in, 0, 8);
unchecked {
return (long)(
((long)(i64in[0] & 0xff) << 56) |
((long)(i64in[1] & 0xff) << 48) |
((long)(i64in[2] & 0xff) << 40) |
((long)(i64in[3] & 0xff) << 32) |
((long)(i64in[4] & 0xff) << 24) |
((long)(i64in[5] & 0xff) << 16) |
((long)(i64in[6] & 0xff) << 8) |
((long)(i64in[7] & 0xff)));
unchecked
{
return (long)(
((long)(i64in[0] & 0xff) << 56) |
((long)(i64in[1] & 0xff) << 48) |
((long)(i64in[2] & 0xff) << 40) |
((long)(i64in[3] & 0xff) << 32) |
((long)(i64in[4] & 0xff) << 24) |
((long)(i64in[5] & 0xff) << 16) |
((long)(i64in[6] & 0xff) << 8) |
((long)(i64in[7] & 0xff)));
}
}
@ -378,7 +378,7 @@ namespace Thrift.Protocol
trans.ReadAll(buf, 0, size);
return buf;
}
private string ReadStringBody(int size)
private string ReadStringBody(int size)
{
byte[] buf = new byte[size];
trans.ReadAll(buf, 0, size);

View File

@ -44,9 +44,9 @@ namespace Thrift.Protocol
private const byte TYPE_BITS = 0x07; // 0000 0111
private const int TYPE_SHIFT_AMOUNT = 5;
/**
* All of the on-wire type codes.
*/
/// <summary>
/// All of the on-wire type codes.
/// </summary>
private static class Types
{
public const byte STOP = 0x00;
@ -64,32 +64,29 @@ namespace Thrift.Protocol
public const byte STRUCT = 0x0C;
}
/**
* Used to keep track of the last field for the current and previous structs,
* so we can do the delta stuff.
*/
/// <summary>
/// Used to keep track of the last field for the current and previous structs,
/// so we can do the delta stuff.
/// </summary>
private Stack<short> lastField_ = new Stack<short>(15);
private short lastFieldId_ = 0;
/**
* If we encounter a boolean field begin, save the TField here so it can
* have the value incorporated.
*/
/// <summary>
/// If we encounter a boolean field begin, save the TField here so it can
/// have the value incorporated.
/// </summary>
private Nullable<TField> booleanField_;
/**
* If we Read a field header, and it's a boolean field, save the boolean
* value here so that ReadBool can use it.
*/
private Nullable<Boolean> boolValue_;
/// <summary>
/// If we Read a field header, and it's a boolean field, save the boolean
/// value here so that ReadBool can use it.
/// </summary>
private Nullable<Boolean> boolValue_;
#region CompactProtocol Factory
/**
* Factory
*/
public class Factory : TProtocolFactory
{
public Factory() { }
@ -127,31 +124,32 @@ namespace Thrift.Protocol
#region Write Methods
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
private byte[] byteDirectBuffer = new byte[1];
private void WriteByteDirect(byte b)
{
byteDirectBuffer[0] = b;
trans.Write(byteDirectBuffer);
}
/**
* Writes a byte without any possibility of all that field header nonsense.
*/
/// <summary>
/// Writes a byte without any possibility of all that field header nonsense.
/// </summary>
private void WriteByteDirect(int n)
{
WriteByteDirect((byte)n);
}
/**
* Write an i32 as a varint. Results in 1-5 bytes on the wire.
* TODO: make a permanent buffer like WriteVarint64?
*/
/// <summary>
/// Write an i32 as a varint. Results in 1-5 bytes on the wire.
/// TODO: make a permanent buffer like WriteVarint64?
/// </summary>
byte[] i32buf = new byte[5];
private void WriteVarint32(uint n)
{
int idx = 0;
@ -174,10 +172,10 @@ namespace Thrift.Protocol
trans.Write(i32buf, 0, idx);
}
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
public override void WriteMessageBegin(TMessage message)
{
WriteByteDirect(PROTOCOL_ID);
@ -186,33 +184,33 @@ namespace Thrift.Protocol
WriteString(message.Name);
}
/**
* 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
* stack so we can get the field id deltas correct.
*/
/// <summary>
/// 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
/// stack so we can get the field id deltas correct.
/// </summary>
public override void WriteStructBegin(TStruct strct)
{
lastField_.Push(lastFieldId_);
lastFieldId_ = 0;
}
/**
* 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
* of the field stack.
*/
/// <summary>
/// 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
/// of the field stack.
/// </summary>
public override void WriteStructEnd()
{
lastFieldId_ = lastField_.Pop();
}
/**
* 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),
* 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.
*/
/// <summary>
/// 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 (&lt; 15),
/// 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.
/// </summary>
public override void WriteFieldBegin(TField field)
{
if (field.Type == TType.Bool)
@ -226,11 +224,11 @@ namespace Thrift.Protocol
}
}
/**
* The workhorse of WriteFieldBegin. It has the option of doing a
* 'type override' of the type header. This is used specifically in the
* boolean field case.
*/
/// <summary>
/// The workhorse of WriteFieldBegin. It has the option of doing a
/// 'type override' of the type header. This is used specifically in the
/// boolean field case.
/// </summary>
private void WriteFieldBeginInternal(TField field, byte typeOverride)
{
// short lastField = lastField_.Pop();
@ -255,18 +253,18 @@ namespace Thrift.Protocol
// lastField_.push(field.id);
}
/**
* Write the STOP symbol so we know there are no more fields in this struct.
*/
/// <summary>
/// Write the STOP symbol so we know there are no more fields in this struct.
/// </summary>
public override void WriteFieldStop()
{
WriteByteDirect(Types.STOP);
}
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
public override void WriteMapBegin(TMap map)
{
if (map.Count == 0)
@ -280,28 +278,28 @@ namespace Thrift.Protocol
}
}
/**
* Write a list header.
*/
/// <summary>
/// Write a list header.
/// </summary>
public override void WriteListBegin(TList list)
{
WriteCollectionBegin(list.ElementType, list.Count);
}
/**
* Write a set header.
*/
/// <summary>
/// Write a set header.
/// </summary>
public override void WriteSetBegin(TSet set)
{
WriteCollectionBegin(set.ElementType, set.Count);
}
/**
* 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
* right type header is for the value and then Write the field header.
* Otherwise, Write a single byte.
*/
/// <summary>
/// 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
/// right type header is for the value and then Write the field header.
/// Otherwise, Write a single byte.
/// </summary>
public override void WriteBool(Boolean b)
{
if (booleanField_ != null)
@ -317,41 +315,41 @@ namespace Thrift.Protocol
}
}
/**
* Write a byte. Nothing to see here!
*/
/// <summary>
/// Write a byte. Nothing to see here!
/// </summary>
public override void WriteByte(sbyte b)
{
WriteByteDirect((byte)b);
}
/**
* Write an I16 as a zigzag varint.
*/
/// <summary>
/// Write an I16 as a zigzag varint.
/// </summary>
public override void WriteI16(short i16)
{
WriteVarint32(intToZigZag(i16));
}
/**
* Write an i32 as a zigzag varint.
*/
/// <summary>
/// Write an i32 as a zigzag varint.
/// </summary>
public override void WriteI32(int i32)
{
WriteVarint32(intToZigZag(i32));
}
/**
* Write an i64 as a zigzag varint.
*/
/// <summary>
/// Write an i64 as a zigzag varint.
/// </summary>
public override void WriteI64(long i64)
{
WriteVarint64(longToZigzag(i64));
}
/**
* Write a double to the wire as 8 bytes.
*/
/// <summary>
/// Write a double to the wire as 8 bytes.
/// </summary>
public override void WriteDouble(double dub)
{
byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -359,18 +357,18 @@ namespace Thrift.Protocol
trans.Write(data);
}
/**
* Write a string to the wire with a varint size preceding.
*/
public override void WriteString(String str)
/// <summary>
/// Write a string to the wire with a varint size preceding.
/// </summary>
public override void WriteString(string str)
{
byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
WriteBinary(bytes, 0, bytes.Length);
}
/**
* Write a byte array, using a varint for the size.
*/
/// <summary>
/// Write a byte array, using a varint for the size.
/// </summary>
public override void WriteBinary(byte[] bin)
{
WriteBinary(bin, 0, bin.Length);
@ -397,10 +395,10 @@ namespace Thrift.Protocol
// Internal writing methods
//
/**
* Abstract method for writing the start of lists and sets. List and sets on
* the wire differ only by the type indicator.
*/
/// <summary>
/// Abstract method for writing the start of lists and sets. List and sets on
/// the wire differ only by the type indicator.
/// </summary>
protected void WriteCollectionBegin(TType elemType, int size)
{
if (size <= 14)
@ -414,9 +412,9 @@ namespace Thrift.Protocol
}
}
/**
* Write an i64 as a varint. Results in 1-10 bytes on the wire.
*/
/// <summary>
/// Write an i64 as a varint. Results in 1-10 bytes on the wire.
/// </summary>
byte[] varint64out = new byte[10];
private void WriteVarint64(ulong n)
{
@ -437,28 +435,28 @@ namespace Thrift.Protocol
trans.Write(varint64out, 0, idx);
}
/**
* Convert l into a zigzag long. This allows negative numbers to be
* represented compactly as a varint.
*/
/// <summary>
/// Convert l into a zigzag long. This allows negative numbers to be
/// represented compactly as a varint.
/// </summary>
private ulong longToZigzag(long n)
{
return (ulong)(n << 1) ^ (ulong)(n >> 63);
}
/**
* Convert n into a zigzag int. This allows negative numbers to be
* represented compactly as a varint.
*/
/// <summary>
/// Convert n into a zigzag int. This allows negative numbers to be
/// represented compactly as a varint.
/// </summary>
private uint intToZigZag(int n)
{
return (uint)(n << 1) ^ (uint)(n >> 31);
}
/**
* Convert a long into little-endian bytes in buf starting at off and going
* until off+7.
*/
/// <summary>
/// Convert a long into little-endian bytes in buf starting at off and going
/// until off+7.
/// </summary>
private void fixedLongToBytes(long n, byte[] buf, int off)
{
buf[off + 0] = (byte)(n & 0xff);
@ -475,9 +473,9 @@ namespace Thrift.Protocol
#region ReadMethods
/**
* Read a message header.
*/
/// <summary>
/// Read a message header.
/// </summary>
public override TMessage ReadMessageBegin()
{
byte protocolId = (byte)ReadByte();
@ -493,14 +491,14 @@ namespace Thrift.Protocol
}
byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
int seqid = (int)ReadVarint32();
String messageName = ReadString();
string messageName = ReadString();
return new TMessage(messageName, (TMessageType)type, seqid);
}
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
public override TStruct ReadStructBegin()
{
lastField_.Push(lastFieldId_);
@ -508,19 +506,19 @@ namespace Thrift.Protocol
return ANONYMOUS_STRUCT;
}
/**
* Doesn't actually consume any wire data, just removes the last field for
* this struct from the field stack.
*/
/// <summary>
/// Doesn't actually consume any wire data, just removes the last field for
/// this struct from the field stack.
/// </summary>
public override void ReadStructEnd()
{
// consume the last field we Read off the wire.
lastFieldId_ = lastField_.Pop();
}
/**
* Read a field header off the wire.
*/
/// <summary>
/// Read a field header off the wire.
/// </summary>
public override TField ReadFieldBegin()
{
byte type = (byte)ReadByte();
@ -560,11 +558,11 @@ namespace Thrift.Protocol
return field;
}
/**
* 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
* "correct" types.
*/
/// <summary>
/// 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
/// "correct" types.
/// </summary>
public override TMap ReadMapBegin()
{
int size = (int)ReadVarint32();
@ -572,12 +570,12 @@ namespace Thrift.Protocol
return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
}
/**
* 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
* of the element type header will be 0xF, and a varint will follow with the
* true size.
*/
/// <summary>
/// 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
/// of the element type header will be 0xF, and a varint will follow with the
/// true size.
/// </summary>
public override TList ReadListBegin()
{
byte size_and_type = (byte)ReadByte();
@ -590,22 +588,22 @@ namespace Thrift.Protocol
return new TList(type, size);
}
/**
* 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
* of the element type header will be 0xF, and a varint will follow with the
* true size.
*/
/// <summary>
/// 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
/// of the element type header will be 0xF, and a varint will follow with the
/// true size.
/// </summary>
public override TSet ReadSetBegin()
{
return new TSet(ReadListBegin());
}
/**
* 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
* pre-stored value. Otherwise, Read a byte.
*/
/// <summary>
/// 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
/// pre-stored value. Otherwise, Read a byte.
/// </summary>
public override Boolean ReadBool()
{
if (boolValue_ != null)
@ -618,42 +616,42 @@ namespace Thrift.Protocol
}
byte[] byteRawBuf = new byte[1];
/**
* Read a single byte off the wire. Nothing interesting here.
*/
/// <summary>
/// Read a single byte off the wire. Nothing interesting here.
/// </summary>
public override sbyte ReadByte()
{
trans.ReadAll(byteRawBuf, 0, 1);
return (sbyte)byteRawBuf[0];
}
/**
* Read an i16 from the wire as a zigzag varint.
*/
/// <summary>
/// Read an i16 from the wire as a zigzag varint.
/// </summary>
public override short ReadI16()
{
return (short)zigzagToInt(ReadVarint32());
}
/**
* Read an i32 from the wire as a zigzag varint.
*/
/// <summary>
/// Read an i32 from the wire as a zigzag varint.
/// </summary>
public override int ReadI32()
{
return zigzagToInt(ReadVarint32());
}
/**
* Read an i64 from the wire as a zigzag varint.
*/
/// <summary>
/// Read an i64 from the wire as a zigzag varint.
/// </summary>
public override long ReadI64()
{
return zigzagToLong(ReadVarint64());
}
/**
* No magic here - just Read a double off the wire.
*/
/// <summary>
/// No magic here - just Read a double off the wire.
/// </summary>
public override double ReadDouble()
{
byte[] longBits = new byte[8];
@ -661,10 +659,10 @@ namespace Thrift.Protocol
return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
}
/**
* Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
*/
public override String ReadString()
/// <summary>
/// Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
/// </summary>
public override string ReadString()
{
int length = (int)ReadVarint32();
@ -676,9 +674,9 @@ namespace Thrift.Protocol
return Encoding.UTF8.GetString(ReadBinary(length));
}
/**
* Read a byte[] from the wire.
*/
/// <summary>
/// Read a byte[] from the wire.
/// </summary>
public override byte[] ReadBinary()
{
int length = (int)ReadVarint32();
@ -689,9 +687,9 @@ namespace Thrift.Protocol
return buf;
}
/**
* Read a byte[] of a known length from the wire.
*/
/// <summary>
/// Read a byte[] of a known length from the wire.
/// </summary>
private byte[] ReadBinary(int length)
{
if (length == 0) return new byte[0];
@ -715,10 +713,10 @@ namespace Thrift.Protocol
// Internal Reading methods
//
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
private uint ReadVarint32()
{
uint result = 0;
@ -733,10 +731,10 @@ namespace Thrift.Protocol
return result;
}
/**
* 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.
*/
/// <summary>
/// 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.
/// </summary>
private ulong ReadVarint64()
{
int shift = 0;
@ -758,27 +756,27 @@ namespace Thrift.Protocol
// encoding helpers
//
/**
* Convert from zigzag int to int.
*/
/// <summary>
/// Convert from zigzag int to int.
/// </summary>
private int zigzagToInt(uint n)
{
return (int)(n >> 1) ^ (-(int)(n & 1));
}
/**
* Convert from zigzag long to long.
*/
/// <summary>
/// Convert from zigzag long to long.
/// </summary>
private long zigzagToLong(ulong n)
{
return (long)(n >> 1) ^ (-(long)(n & 1));
}
/**
* 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,
* you just get a messed up int.
*/
/// <summary>
/// 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,
/// you just get a messed up int.
/// </summary>
private long bytesToLong(byte[] bytes)
{
return
@ -802,10 +800,10 @@ namespace Thrift.Protocol
return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
}
/**
* Given a TCompactProtocol.Types constant, convert it to its corresponding
* TType value.
*/
/// <summary>
/// Given a TCompactProtocol.Types constant, convert it to its corresponding
/// TType value.
/// </summary>
private TType getTType(byte type)
{
switch ((byte)(type & 0x0f))
@ -840,9 +838,9 @@ namespace Thrift.Protocol
}
}
/**
* Given a TType value, find the appropriate TCompactProtocol.Types constant.
*/
/// <summary>
/// Given a TType value, find the appropriate TCompactProtocol.Types constant.
/// </summary>
private byte getCompactType(TType ttype)
{
return ttypeToCompactType[(int)ttype];

View File

@ -29,18 +29,18 @@ namespace Thrift.Protocol
{
/// <summary>
/// JSON protocol implementation for thrift.
///
/// <para/>
/// This is a full-featured protocol supporting Write and Read.
///
/// <para/>
/// Please see the C++ class header for a detailed description of the
/// protocol's wire format.
///
/// <para/>
/// Adapted from the Java version.
/// </summary>
public class TJSONProtocol : TProtocol
{
/// <summary>
/// Factory for JSON protocol objects
/// Factory for JSON protocol objects.
/// </summary>
public class Factory : TProtocolFactory
{
@ -179,11 +179,11 @@ namespace Thrift.Protocol
return result;
}
///<summary>
/// <summary>
/// Base class for tracking JSON contexts that may require
/// inserting/Reading additional JSON syntax characters
/// This base context does nothing.
///</summary>
/// </summary>
protected class JSONBaseContext
{
protected TJSONProtocol proto;
@ -200,10 +200,10 @@ namespace Thrift.Protocol
public virtual bool EscapeNumbers() { return false; }
}
///<summary>
/// <summary>
/// Context for JSON lists. Will insert/Read commas before each item except
/// for the first one
///</summary>
/// </summary>
protected class JSONListContext : JSONBaseContext
{
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
/// 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
/// escaped in quotes (since JSON keys must be strings).
///</summary>
/// </summary>
protected class JSONPairContext : JSONBaseContext
{
public JSONPairContext(TJSONProtocol proto)
@ -290,9 +290,9 @@ namespace Thrift.Protocol
}
}
///<summary>
/// <summary>
/// Holds up to one byte from the transport
///</summary>
/// </summary>
protected class LookaheadReader
{
protected TJSONProtocol proto;
@ -305,10 +305,10 @@ namespace Thrift.Protocol
private bool hasData;
private byte[] data = new byte[1];
///<summary>
/// <summary>
/// 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.
///</summary>
/// </summary>
public byte Read()
{
if (hasData)
@ -322,10 +322,10 @@ namespace Thrift.Protocol
return data[0];
}
///<summary>
/// <summary>
/// Return the next byte to be Read without consuming, filling the data
/// buffer if it has not been filled alReady.
///</summary>
/// </summary>
public byte Peek()
{
if (!hasData)
@ -349,26 +349,26 @@ namespace Thrift.Protocol
// Reader that manages a 1-byte buffer
protected LookaheadReader reader;
///<summary>
/// <summary>
/// Push a new JSON context onto the stack.
///</summary>
/// </summary>
protected void PushContext(JSONBaseContext c)
{
contextStack.Push(context);
context = c;
}
///<summary>
/// <summary>
/// Pop the last JSON context off the stack
///</summary>
/// </summary>
protected void PopContext()
{
context = contextStack.Pop();
}
///<summary>
/// <summary>
/// TJSONProtocol Constructor
///</summary>
/// </summary>
public TJSONProtocol(TTransport trans)
: base(trans)
{
@ -379,11 +379,11 @@ namespace Thrift.Protocol
// Temporary buffer used by several methods
private byte[] tempBuffer = new byte[4];
///<summary>
/// <summary>
/// Read a byte that must match b[0]; otherwise an exception is thrown.
/// Marked protected to avoid synthetic accessor in JSONListContext.Read
/// and JSONPairContext.Read
///</summary>
/// </summary>
protected void ReadJSONSyntaxChar(byte[] b)
{
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
/// corresponding hex value
///</summary>
/// </summary>
private static byte HexVal(byte ch)
{
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
///</summary>
/// </summary>
private static byte HexChar(byte val)
{
val &= 0x0F;
@ -433,9 +433,9 @@ namespace Thrift.Protocol
}
}
///<summary>
/// <summary>
/// Write the bytes in array buf as a JSON characters, escaping as needed
///</summary>
/// </summary>
private void WriteJSONString(byte[] b)
{
context.Write();
@ -479,14 +479,14 @@ namespace Thrift.Protocol
trans.Write(QUOTE);
}
///<summary>
/// <summary>
/// Write out number as a JSON value. If the context dictates so, it will be
/// wrapped in quotes to output as a JSON string.
///</summary>
/// </summary>
private void WriteJSONInteger(long num)
{
context.Write();
String str = num.ToString();
string str = num.ToString();
bool escapeNum = context.EscapeNumbers();
if (escapeNum)
@ -498,14 +498,14 @@ namespace Thrift.Protocol
trans.Write(QUOTE);
}
///<summary>
/// <summary>
/// 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.
///</summary>
/// </summary>
private void WriteJSONDouble(double num)
{
context.Write();
String str = num.ToString("G17", CultureInfo.InvariantCulture);
string str = num.ToString("G17", CultureInfo.InvariantCulture);
bool special = false;
switch (str[0])
@ -532,10 +532,10 @@ namespace Thrift.Protocol
if (escapeNum)
trans.Write(QUOTE);
}
///<summary>
/// <summary>
/// Write out contents of byte array b as a JSON string with base-64 encoded
/// data
///</summary>
/// </summary>
private void WriteJSONBase64(byte[] b)
{
context.Write();
@ -698,7 +698,7 @@ namespace Thrift.Protocol
WriteJSONDouble(dub);
}
public override void WriteString(String str)
public override void WriteString(string str)
{
byte[] b = utf8Encoding.GetBytes(str);
WriteJSONString(b);
@ -713,10 +713,10 @@ namespace Thrift.Protocol
* Reading methods.
*/
///<summary>
/// <summary>
/// Read in a JSON string, unescaping as appropriate.. Skip Reading from the
/// context if skipContext is true.
///</summary>
/// </summary>
private byte[] ReadJSONString(bool skipContext)
{
MemoryStream buffer = new MemoryStream();
@ -803,9 +803,9 @@ namespace Thrift.Protocol
return buffer.ToArray();
}
///<summary>
/// <summary>
/// Return true if the given byte could be a valid part of a JSON number.
///</summary>
/// </summary>
private bool IsJSONNumeric(byte b)
{
switch (b)
@ -830,11 +830,11 @@ namespace Thrift.Protocol
return false;
}
///<summary>
/// <summary>
/// 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.
////</summary>
private String ReadJSONNumericChars()
/// </summary>
private string ReadJSONNumericChars()
{
StringBuilder strbld = new StringBuilder();
while (true)
@ -849,9 +849,9 @@ namespace Thrift.Protocol
return strbld.ToString();
}
///<summary>
/// <summary>
/// Read in a JSON number. If the context dictates, Read in enclosing quotes.
///</summary>
/// </summary>
private long ReadJSONInteger()
{
context.Read();
@ -859,7 +859,7 @@ namespace Thrift.Protocol
{
ReadJSONSyntaxChar(QUOTE);
}
String str = ReadJSONNumericChars();
string str = ReadJSONNumericChars();
if (context.EscapeNumbers())
{
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
/// when expected or if wrapped in quotes when not expected.
///</summary>
/// </summary>
private double ReadJSONDouble()
{
context.Read();
if (reader.Peek() == QUOTE[0])
{
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) &&
!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.
///</summary>
/// </summary>
private byte[] ReadJSONBase64()
{
byte[] b = ReadJSONString(false);
@ -989,7 +989,7 @@ namespace Thrift.Protocol
}
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.SeqID = (int)ReadJSONInteger();
return message;
@ -1108,10 +1108,10 @@ namespace Thrift.Protocol
return ReadJSONDouble();
}
public override String ReadString()
public override string ReadString()
{
var buf = ReadJSONString(false);
return utf8Encoding.GetString(buf,0,buf.Length);
return utf8Encoding.GetString(buf, 0, buf.Length);
}
public override byte[] ReadBinary()

View File

@ -29,74 +29,77 @@ using System.IO;
namespace Thrift.Protocol
{
/**
* TMultiplexedProcessor is a TProcessor allowing a single TServer to provide multiple services.
* To do so, you instantiate the processor and then register additional processors with it,
* as shown in the following example:
*
* TMultiplexedProcessor processor = new TMultiplexedProcessor();
*
* processor.registerProcessor(
* "Calculator",
* new Calculator.Processor(new CalculatorHandler()));
*
* processor.registerProcessor(
* "WeatherReport",
* new WeatherReport.Processor(new WeatherReportHandler()));
*
* TServerTransport t = new TServerSocket(9090);
* TSimpleServer server = new TSimpleServer(processor, t);
*
* server.serve();
*/
/// <summary>
/// <see cref="TMultiplexedProcessor"/> is a <see cref="TProcessor"/> allowing a single <see cref="Thrift.Server.TServer"/>
/// to provide multiple services.
/// <para/>
/// To do so, you instantiate the processor and then register additional processors with it,
/// as shown in the following example:
/// <para/>
/// <code>
/// TMultiplexedProcessor processor = new TMultiplexedProcessor();
///
/// processor.registerProcessor(
/// "Calculator",
/// new Calculator.Processor(new CalculatorHandler()));
///
/// processor.registerProcessor(
/// "WeatherReport",
/// new WeatherReport.Processor(new WeatherReportHandler()));
///
/// TServerTransport t = new TServerSocket(9090);
/// TSimpleServer server = new TSimpleServer(processor, t);
///
/// server.serve();
/// </code>
/// </summary>
public class TMultiplexedProcessor : TProcessor
{
private Dictionary<String,TProcessor> ServiceProcessorMap = new Dictionary<String,TProcessor>();
private Dictionary<string, TProcessor> ServiceProcessorMap = new Dictionary<string, TProcessor>();
/**
* '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.
*
* Args:
* - serviceName Name of a service, has to be identical to the name
* declared in the Thrift IDL, e.g. "WeatherReport".
* - processor Implementation of a service, usually referred to as "handlers",
* e.g. WeatherReportHandler implementing WeatherReport.Iface.
*/
public void RegisterProcessor(String serviceName, TProcessor processor)
/// <summary>
/// '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.
///
/// Args:
/// - serviceName Name of a service, has to be identical to the name
/// declared in the Thrift IDL, e.g. "WeatherReport".
/// - processor Implementation of a service, usually referred to as "handlers",
/// e.g. WeatherReportHandler implementing WeatherReport.Iface.
/// </summary>
public void RegisterProcessor(string serviceName, TProcessor 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);
oprot.WriteMessageBegin(newMessage);
appex.Write( oprot);
appex.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
}
/**
* This implementation of process performs the following steps:
*
* - Read the beginning of the message.
* - Extract the service name from the message.
* - Using the service name to locate the appropriate processor.
* - Dispatch to the processor, with a decorated instance of TProtocol
* that allows readMessageBegin() to return the original TMessage.
*
* Throws an exception if
* - the message type is not CALL or ONEWAY,
* - the service name was not found in the message, or
* - the service name has not been RegisterProcessor()ed.
*/
/// <summary>
/// This implementation of process performs the following steps:
///
/// - Read the beginning of the message.
/// - Extract the service name from the message.
/// - Using the service name to locate the appropriate processor.
/// - Dispatch to the processor, with a decorated instance of TProtocol
/// that allows readMessageBegin() to return the original TMessage.
/// <para/>
/// Throws an exception if
/// - the message type is not CALL or ONEWAY,
/// - the service name was not found in the message, or
/// - the service name has not been RegisterProcessor()ed.
/// </summary>
public bool Process(TProtocol iprot, TProtocol oprot)
{
/* Use the actual underlying protocol (e.g. TBinaryProtocol) to read the
@ -155,17 +158,17 @@ namespace Thrift.Protocol
}
/**
* 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
* the standard format, without the service name prepended to TMessage.name.
*/
/// <summary>
/// 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
/// the standard format, without the service name prepended to TMessage.name.
/// </summary>
private class StoredMessageProtocol : TProtocolDecorator
{
TMessage MsgBegin;
public StoredMessageProtocol(TProtocol protocol, TMessage messageBegin)
:base(protocol)
: base(protocol)
{
this.MsgBegin = messageBegin;
}

View File

@ -29,63 +29,62 @@ using System.Collections.Generic;
namespace Thrift.Protocol
{
/**
* TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
* client to communicate with a multiplexing Thrift server, by prepending the service name
* to the function name during function calls.
*
* NOTE: THIS IS NOT TO BE USED BY SERVERS.
* On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
*
* This example uses a single socket transport to invoke two services:
*
* TSocket transport = new TSocket("localhost", 9090);
* transport.open();
*
* TBinaryProtocol protocol = new TBinaryProtocol(transport);
*
* TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
* Calculator.Client service = new Calculator.Client(mp);
*
* TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
* WeatherReport.Client service2 = new WeatherReport.Client(mp2);
*
* System.out.println(service.add(2,2));
* System.out.println(service2.getTemperature());
*
*/
/// <summary>
/// TMultiplexedProtocol is a protocol-independent concrete decorator that allows a Thrift
/// client to communicate with a multiplexing Thrift server, by prepending the service name
/// to the function name during function calls.
/// <para/>
/// NOTE: THIS IS NOT TO BE USED BY SERVERS.
/// On the server, use TMultiplexedProcessor to handle requests from a multiplexing client.
/// <para/>
/// This example uses a single socket transport to invoke two services:
/// <code>
/// TSocket transport = new TSocket("localhost", 9090);
/// transport.open();
///
/// TBinaryProtocol protocol = new TBinaryProtocol(transport);
///
/// TMultiplexedProtocol mp = new TMultiplexedProtocol(protocol, "Calculator");
/// Calculator.Client service = new Calculator.Client(mp);
///
/// TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "WeatherReport");
/// WeatherReport.Client service2 = new WeatherReport.Client(mp2);
///
/// System.out.println(service.add(2,2));
/// System.out.println(service2.getTemperature());
/// </code>
/// </summary>
public class TMultiplexedProtocol : TProtocolDecorator
{
/** Used to delimit the service name from the function name */
public static String SEPARATOR = ":";
/// <summary>
/// Used to delimit the service name from the function name.
/// </summary>
public static string SEPARATOR = ":";
private String ServiceName;
private string ServiceName;
/**
* Wrap the specified protocol, allowing it to be used to communicate with a
* multiplexing server. The <code>serviceName</code> is required as it is
* prepended to the message header so that the multiplexing server can broker
* the function call to the proper service.
*
* Args:
* protocol Your communication protocol of choice, e.g. TBinaryProtocol
* serviceName The service name of the service communicating via this protocol.
*/
public TMultiplexedProtocol(TProtocol protocol, String serviceName)
/// <summary>
/// Wrap the specified protocol, allowing it to be used to communicate with a
/// multiplexing server. The <paramref name="serviceName"/> is required as it is
/// prepended to the message header so that the multiplexing server can broker
/// the function call to the proper service.
/// </summary>
/// <param name="protocol">Your communication protocol of choice, e.g. <see cref="TBinaryProtocol"/>.</param>
/// <param name="serviceName">The service name of the service communicating via this protocol.</param>
public TMultiplexedProtocol(TProtocol protocol, string serviceName)
: base(protocol)
{
ServiceName = serviceName;
}
/**
* Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
* Args:
* tMessage The original message.
*/
/// <summary>
/// Prepends the service name to the function name, separated by TMultiplexedProtocol.SEPARATOR.
/// </summary>
/// <param name="tMessage">The original message.</param>
public override void WriteMessageBegin(TMessage tMessage)
{
switch(tMessage.Type)
switch (tMessage.Type)
{
case TMessageType.Call:
case TMessageType.Oneway:
@ -101,5 +100,4 @@ namespace Thrift.Protocol
}
}
}
}

View File

@ -108,7 +108,8 @@ namespace Thrift.Protocol
public abstract void WriteI32(int i32);
public abstract void WriteI64(long i64);
public abstract void WriteDouble(double d);
public virtual void WriteString(string s) {
public virtual void WriteString(string s)
{
WriteBinary(Encoding.UTF8.GetBytes(s));
}
public abstract void WriteBinary(byte[] b);
@ -131,7 +132,8 @@ namespace Thrift.Protocol
public abstract int ReadI32();
public abstract long ReadI64();
public abstract double ReadDouble();
public virtual string ReadString() {
public virtual string ReadString()
{
var buf = ReadBinary();
return Encoding.UTF8.GetString(buf, 0, buf.Length);
}

View File

@ -28,26 +28,25 @@ using System.Collections.Generic;
namespace Thrift.Protocol
{
/**
* TProtocolDecorator forwards all requests to an enclosed TProtocol instance,
* 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,
* it does not modify the behaviour of the enclosed TProtocol.
*
* See p.175 of Design Patterns (by Gamma et al.)
* See TMultiplexedProtocol
*/
/// <summary>
/// <see cref="TProtocolDecorator"/> forwards all requests to an enclosed <see cref="TProtocol"/> instance,
/// 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,
/// it does not modify the behaviour of the enclosed <see cref="TProtocol"/>.
/// <para/>
/// See p.175 of Design Patterns (by Gamma et al.)
/// </summary>
/// <seealso cref="TMultiplexedProtocol"/>
public abstract class TProtocolDecorator : TProtocol
{
private TProtocol WrappedProtocol;
/**
* Encloses the specified protocol.
* @param protocol All operations will be forward to this protocol. Must be non-null.
*/
/// <summary>
/// Encloses the specified protocol.
/// </summary>
/// <param name="protocol">All operations will be forward to this protocol. Must be non-null.</param>
public TProtocolDecorator(TProtocol protocol)
: base( protocol.Transport)
: base(protocol.Transport)
{
WrappedProtocol = protocol;
@ -104,7 +103,7 @@ namespace Thrift.Protocol
}
public override void WriteListEnd()
{
{
WrappedProtocol.WriteListEnd();
}
@ -148,7 +147,7 @@ namespace Thrift.Protocol
WrappedProtocol.WriteDouble(v);
}
public override void WriteString(String s)
public override void WriteString(string s)
{
WrappedProtocol.WriteString(s);
}
@ -248,7 +247,7 @@ namespace Thrift.Protocol
return WrappedProtocol.ReadDouble();
}
public override String ReadString()
public override string ReadString()
{
return WrappedProtocol.ReadString();
}

View File

@ -48,13 +48,13 @@ namespace Thrift.Protocol
type_ = type;
}
public TProtocolException(int type, String message)
public TProtocolException(int type, string message)
: base(message)
{
type_ = type;
}
public TProtocolException(String message)
public TProtocolException(string message)
: base(message)
{
}

View File

@ -98,7 +98,6 @@ namespace Thrift.Protocol
default:
throw new TProtocolException(TProtocolException.INVALID_DATA, "Unknown data type " + type.ToString("d"));
}
}
finally
{

View File

@ -28,128 +28,128 @@ using System.IO;
namespace Thrift.Server
{
public abstract class TServer
{
//Attributes
protected TProcessorFactory processorFactory;
protected TServerTransport serverTransport;
protected TTransportFactory inputTransportFactory;
protected TTransportFactory outputTransportFactory;
protected TProtocolFactory inputProtocolFactory;
protected TProtocolFactory outputProtocolFactory;
protected TServerEventHandler serverEventHandler = null;
public abstract class TServer
{
//Attributes
protected TProcessorFactory processorFactory;
protected TServerTransport serverTransport;
protected TTransportFactory inputTransportFactory;
protected TTransportFactory outputTransportFactory;
protected TProtocolFactory inputProtocolFactory;
protected TProtocolFactory outputProtocolFactory;
protected TServerEventHandler serverEventHandler = null;
//Methods
public void setEventHandler(TServerEventHandler seh)
{
serverEventHandler = seh;
}
public TServerEventHandler getEventHandler()
{
return serverEventHandler;
}
//Methods
public void setEventHandler(TServerEventHandler seh)
{
serverEventHandler = seh;
}
public TServerEventHandler getEventHandler()
{
return serverEventHandler;
}
//Log delegation
public delegate void LogDelegate(string str);
private LogDelegate _logDelegate;
protected LogDelegate logDelegate
{
get { return _logDelegate; }
set { _logDelegate = (value != null) ? value : DefaultLogDelegate; }
}
protected static void DefaultLogDelegate(string s)
{
Console.Error.WriteLine(s);
}
//Log delegation
public delegate void LogDelegate(string str);
private LogDelegate _logDelegate;
protected LogDelegate logDelegate
{
get { return _logDelegate; }
set { _logDelegate = (value != null) ? value : DefaultLogDelegate; }
}
protected static void DefaultLogDelegate(string s)
{
Console.Error.WriteLine(s);
}
//Construction
public TServer(TProcessor processor,
TServerTransport serverTransport)
: this(processor, serverTransport,
new TTransportFactory(),
new TTransportFactory(),
new TBinaryProtocol.Factory(),
new TBinaryProtocol.Factory(),
DefaultLogDelegate)
{
}
//Construction
public TServer(TProcessor processor,
TServerTransport serverTransport)
: this(processor, serverTransport,
new TTransportFactory(),
new TTransportFactory(),
new TBinaryProtocol.Factory(),
new TBinaryProtocol.Factory(),
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,
TTransportFactory inputTransportFactory,
TTransportFactory outputTransportFactory,
TProtocolFactory inputProtocolFactory,
TProtocolFactory outputProtocolFactory,
LogDelegate logDelegate)
: this(processor,
serverTransport,
new TTransportFactory(),
new TTransportFactory(),
new TBinaryProtocol.Factory(),
new TBinaryProtocol.Factory(),
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(TProcessor processor,
TServerTransport serverTransport,
TTransportFactory transportFactory)
: this(processor,
serverTransport,
transportFactory,
transportFactory,
new TBinaryProtocol.Factory(),
new TBinaryProtocol.Factory(),
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;
}
public TServer(TProcessor processor,
TServerTransport serverTransport,
TTransportFactory transportFactory,
TProtocolFactory protocolFactory)
: this(processor,
serverTransport,
transportFactory,
transportFactory,
protocolFactory,
protocolFactory,
DefaultLogDelegate)
{
//Abstract Interface
public abstract void Serve();
public abstract void Stop();
}
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();
}
}

View File

@ -25,26 +25,29 @@ using System;
namespace Thrift.Server
{
/// <summary>
/// Interface implemented by server users to handle events from the server
/// </summary>
public interface TServerEventHandler
{
/// <summary>
/// Called before the server begins */
/// Interface implemented by server users to handle events from the server.
/// </summary>
void preServe();
/// <summary>
/// Called when a new client has connected and is about to being processing */
/// </summary>
Object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
/// <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);
};
public interface TServerEventHandler
{
/// <summary>
/// Called before the server begins.
/// </summary>
void preServe();
/// <summary>
/// Called when a new client has connected and is about to being processing.
/// </summary>
object createContext(Thrift.Protocol.TProtocol input, Thrift.Protocol.TProtocol output);
/// <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);
};
}

View File

@ -27,154 +27,154 @@ using Thrift.Protocol;
namespace Thrift.Server
{
/// <summary>
/// Simple single-threaded server for testing
/// </summary>
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)
/// <summary>
/// Simple single-threaded server for testing.
/// </summary>
public class TSimpleServer : TServer
{
}
private bool stop = false;
public TSimpleServer(TProcessor processor,
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
{
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
public TSimpleServer(TProcessor processor,
TServerTransport serverTransport)
: base(processor, serverTransport, new TTransportFactory(), new TTransportFactory(), new TBinaryProtocol.Factory(), new TBinaryProtocol.Factory(), DefaultLogDelegate)
{
using (client = serverTransport.Accept())
{
processor = processorFactory.GetProcessor(client);
if (client != null)
}
public TSimpleServer(TProcessor processor,
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))
{
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;
}
}
}
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);
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
if (serverEventHandler != null)
serverEventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
}
public override void Stop()
{
stop = true;
serverTransport.Close();
}
}
public override void Stop()
{
stop = true;
serverTransport.Close();
}
}
}

View File

@ -28,268 +28,268 @@ using Thrift.Transport;
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>
/// Use new ThreadPool thread for each new client connection
/// Server that uses C# built-in ThreadPool to spawn threads when handling requests.
/// </summary>
public override void Serve()
public class TThreadPoolServer : TServer
{
try
{
serverTransport.Listen();
}
catch (TTransportException ttx)
{
logDelegate("Error, could not listen on ServerTransport: " + ttx);
return;
}
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;
//Fire the preServe server event when server is up but before any client connections
if (serverEventHandler != null)
serverEventHandler.preServe();
while (!stop)
{
int failureCount = 0;
try
public struct Configuration
{
TTransport client = serverTransport.Accept();
ThreadPool.QueueUserWorkItem(this.Execute, client);
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;
}
}
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)
{
try
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)
{
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
public TThreadPoolServer(TProcessor processor,
TServerTransport serverTransport,
TTransportFactory transportFactory,
TProtocolFactory protocolFactory)
: this(new TSingletonProcessorFactory(processor), serverTransport,
transportFactory, transportFactory,
protocolFactory, protocolFactory,
new Configuration(), DefaultLogDelegate)
{
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
}
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>
/// 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)
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
//Process client requests until client disconnects
serverEventHandler.preServe();
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();
}
}
}
int failureCount = 0;
try
{
TTransport client = serverTransport.Accept();
ThreadPool.QueueUserWorkItem(this.Execute, client);
}
catch (TTransportException ttx)
{
if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
{
++failureCount;
logDelegate(ttx.ToString());
}
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();
}
}
}
}

View File

@ -26,258 +26,257 @@ using Thrift.Transport;
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>
/// 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>
public override void Serve()
public class TThreadedServer : TServer
{
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;
}
private const int DEFAULT_MAX_THREADS = 100;
private volatile bool stop = false;
private readonly int maxThreads;
//Fire the preServe server event when server is up but before any client connections
if (serverEventHandler != null)
serverEventHandler.preServe();
private Queue<TTransport> clientQueue;
private THashSet<Thread> clientThreads;
private object clientLock;
private Thread workerThread;
while (!stop)
{
int failureCount = 0;
try
public int ClientThreadsCount
{
TTransport client = serverTransport.Accept();
lock (clientLock)
{
clientQueue.Enqueue(client);
Monitor.Pulse(clientLock);
}
get { return clientThreads.Count; }
}
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)
{
try
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)
{
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>
/// Loops on processing a client forever
/// threadContext will be a TTransport instance
/// </summary>
/// <param name="threadContext"></param>
private void Execute()
{
while (!stop)
{
TTransport client;
Thread t;
lock (clientLock)
public TThreadedServer(TProcessorFactory processorFactory,
TServerTransport serverTransport,
TTransportFactory transportFactory,
TProtocolFactory protocolFactory)
: this(processorFactory, serverTransport,
transportFactory, transportFactory,
protocolFactory, protocolFactory,
DEFAULT_MAX_THREADS, DefaultLogDelegate)
{
//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
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)
{
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
this.maxThreads = maxThreads;
clientQueue = new Queue<TTransport>();
clientLock = new object();
clientThreads = new THashSet<Thread>();
}
/// <summary>
/// Use new Thread for each new client connection. block until numConnections &lt; 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)
connectionContext = serverEventHandler.createContext(inputProtocol, outputProtocol);
//Process client requests until client disconnects
serverEventHandler.preServe();
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;
int failureCount = 0;
try
{
TTransport client = serverTransport.Accept();
lock (clientLock)
{
clientQueue.Enqueue(client);
Monitor.Pulse(clientLock);
}
}
catch (TTransportException ttx)
{
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);
}
}
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 (stop)
{
try
{
serverTransport.Close();
}
catch (TTransportException ttx)
{
logDelegate("TServeTransport failed on close: " + ttx.Message);
}
stop = false;
}
}
}
}
public override void Stop()
{
stop = true;
serverTransport.Close();
//clean up all the threads myself
workerThread.Abort();
foreach (Thread t in clientThreads)
{
t.Abort();
}
/// <summary>
/// Loops on processing a client forever
/// </summary>
private void Execute()
{
while (!stop)
{
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
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();
}
}
}
}
}

View File

@ -103,7 +103,7 @@ namespace Thrift
oprot.WriteStructBegin(struc);
if (!String.IsNullOrEmpty(Message))
if (!string.IsNullOrEmpty(Message))
{
field.Name = "message";
field.Type = TType.String;

View File

@ -31,7 +31,7 @@ namespace Thrift
{
}
public TException( string message)
public TException(string message)
: base(message)
{
}

View File

@ -42,7 +42,7 @@ namespace Thrift
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;
if (handlerServerRef != null)

View File

@ -17,7 +17,7 @@
* under the License.
*/
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

View File

@ -154,11 +154,11 @@ namespace Thrift.Transport
{
if (disposing)
{
if(inputBuffer != null)
if (inputBuffer != null)
inputBuffer.Dispose();
if(outputBuffer != null)
if (outputBuffer != null)
outputBuffer.Dispose();
if(transport != null)
if (transport != null)
transport.Dispose();
}
}

View File

@ -116,8 +116,8 @@ namespace Thrift.Transport
byte[] buf = writeBuffer.GetBuffer();
int len = (int)writeBuffer.Length;
int data_len = len - HeaderSize;
if ( data_len < 0 )
throw new System.InvalidOperationException (); // logic error actually
if (data_len < 0)
throw new System.InvalidOperationException(); // logic error actually
// Inject message header into the reserved buffer space
EncodeFrameSize(data_len, buf);
@ -130,7 +130,7 @@ namespace Thrift.Transport
transport.Flush();
}
private void InitWriteBuffer ()
private void InitWriteBuffer()
{
// Reserve space for message header to be put right before sending it out
writeBuffer.SetLength(HeaderSize);
@ -150,7 +150,7 @@ namespace Thrift.Transport
return
((buf[0] & 0xff) << 24) |
((buf[1] & 0xff) << 16) |
((buf[2] & 0xff) << 8) |
((buf[2] & 0xff) << 8) |
((buf[3] & 0xff));
}
@ -171,11 +171,11 @@ namespace Thrift.Transport
{
if (disposing)
{
if(readBuffer != null)
if (readBuffer != null)
readBuffer.Dispose();
if(writeBuffer != null)
if (writeBuffer != null)
writeBuffer.Dispose();
if(transport != null)
if (transport != null)
transport.Dispose();
}
}

View File

@ -30,7 +30,6 @@ using System.IO.Compression;
namespace Thrift.Transport
{
public class THttpClient : TTransport, IDisposable
{
private readonly Uri uri;
@ -43,7 +42,7 @@ namespace Thrift.Transport
private int readTimeout = 30000;
private IDictionary<String, String> customHeaders = new Dictionary<string, string>();
private IDictionary<string, string> customHeaders = new Dictionary<string, string>();
#if !SILVERLIGHT
private IWebProxy proxy = WebRequest.DefaultWebProxy;
@ -64,7 +63,7 @@ namespace Thrift.Transport
{
set
{
connectTimeout = value;
connectTimeout = value;
}
}
@ -76,7 +75,7 @@ namespace Thrift.Transport
}
}
public IDictionary<String, String> CustomHeaders
public IDictionary<string, string> CustomHeaders
{
get
{
@ -325,7 +324,7 @@ namespace Thrift.Transport
{
try
{
var flushAsyncResult = (FlushAsyncResult) asyncResult;
var flushAsyncResult = (FlushAsyncResult)asyncResult;
if (!flushAsyncResult.IsCompleted)
{
@ -338,7 +337,8 @@ namespace Thrift.Transport
{
throw flushAsyncResult.AsyncException;
}
} finally
}
finally
{
outputStream = new MemoryStream();
}
@ -387,9 +387,9 @@ namespace Thrift.Transport
private volatile Boolean _isCompleted;
private ManualResetEvent _evt;
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;
_state = state;
@ -415,7 +415,7 @@ namespace Thrift.Transport
{
get { return _isCompleted; }
}
private readonly Object _locker = new Object();
private readonly object _locker = new object();
private ManualResetEvent GetEvtHandle()
{
lock (_locker)
@ -452,7 +452,7 @@ namespace Thrift.Transport
}
}
#region " IDisposable Support "
#region " IDisposable Support "
private bool _IsDisposed;
// IDisposable
@ -470,6 +470,6 @@ namespace Thrift.Transport
}
_IsDisposed = true;
}
#endregion
#endregion
}
}

View File

@ -22,45 +22,56 @@ using System.IO;
using System.Reflection;
using Thrift.Protocol;
namespace Thrift.Transport {
public class TMemoryBuffer : TTransport {
namespace Thrift.Transport
{
public class TMemoryBuffer : TTransport
{
private readonly MemoryStream byteStream;
public TMemoryBuffer() {
public TMemoryBuffer()
{
byteStream = new MemoryStream();
}
public TMemoryBuffer(byte[] buf) {
public TMemoryBuffer(byte[] buf)
{
byteStream = new MemoryStream(buf);
}
public override void Open() {
public override void Open()
{
/** do nothing **/
}
public override void Close() {
public override void Close()
{
/** 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);
}
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);
}
public byte[] GetBuffer() {
public byte[] GetBuffer()
{
return byteStream.ToArray();
}
public override bool IsOpen {
public override bool IsOpen
{
get { return true; }
}
public static byte[] Serialize(TAbstractBase s) {
public static byte[] Serialize(TAbstractBase s)
{
var t = new TMemoryBuffer();
var p = new TBinaryProtocol(t);
@ -69,26 +80,33 @@ namespace Thrift.Transport {
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 p = new TBinaryProtocol(trans);
if (typeof (TBase).IsAssignableFrom(typeof (T))) {
var method = typeof (T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
if (typeof(TBase).IsAssignableFrom(typeof(T)))
{
var method = typeof(T).GetMethod("Read", BindingFlags.Instance | BindingFlags.Public);
var t = Activator.CreateInstance<T>();
method.Invoke(t, new object[] {p});
method.Invoke(t, new object[] { p });
return t;
} else {
var method = typeof (T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
return (T) method.Invoke(null, new object[] {p});
}
else
{
var method = typeof(T).GetMethod("Read", BindingFlags.Static | BindingFlags.Public);
return (T)method.Invoke(null, new object[] { p });
}
}
private bool _IsDisposed;
// IDisposable
protected override void Dispose(bool disposing) {
if (!_IsDisposed) {
if (disposing) {
protected override void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (byteStream != null)
byteStream.Dispose();
}
@ -96,4 +114,4 @@ namespace Thrift.Transport {
_IsDisposed = true;
}
}
}
}

View File

@ -108,4 +108,4 @@ namespace Thrift.Transport
client.Dispose();
}
}
}
}

View File

@ -27,150 +27,150 @@ using System.Net.Sockets;
namespace Thrift.Transport
{
public class TServerSocket : TServerTransport
{
/**
* Underlying server with socket
*/
private TcpListener server = null;
public class TServerSocket : TServerTransport
{
/// <summary>
/// Underlying server with socket.
/// </summary>
private TcpListener server = null;
/**
* Port to listen on
*/
private int port = 0;
/// <summary>
/// Port to listen on.
/// </summary>
private int port = 0;
/**
* Timeout for client sockets from accept
*/
private int clientTimeout = 0;
/// <summary>
/// Timeout for client sockets from accept.
/// </summary>
private int clientTimeout = 0;
/**
* Whether or not to wrap new TSocket connections in buffers
*/
private bool useBufferedSockets = false;
/// <summary>
/// Whether or not to wrap new TSocket connections in buffers.
/// </summary>
private bool useBufferedSockets = false;
/**
* Creates a server socket from underlying socket object
*/
public TServerSocket(TcpListener listener)
:this(listener, 0)
{
}
/// <summary>
/// Creates a server socket from underlying socket object.
/// </summary>
public TServerSocket(TcpListener listener)
: this(listener, 0)
{
}
/**
* Creates a server socket from underlying socket object
*/
public TServerSocket(TcpListener listener, int clientTimeout)
{
this.server = listener;
this.clientTimeout = clientTimeout;
}
/// <summary>
/// Creates a server socket from underlying socket object.
/// </summary>
public TServerSocket(TcpListener listener, int clientTimeout)
{
this.server = listener;
this.clientTimeout = clientTimeout;
}
/**
* Creates just a port listening server socket
*/
public TServerSocket(int port)
: this(port, 0)
{
}
/// <summary>
/// Creates just a port listening server socket.
/// </summary>
public TServerSocket(int port)
: this(port, 0)
{
}
/**
* Creates just a port listening server socket
*/
public TServerSocket(int port, int clientTimeout)
:this(port, clientTimeout, false)
{
}
/// <summary>
/// Creates just a port listening server socket.
/// </summary>
public TServerSocket(int port, int clientTimeout)
: this(port, clientTimeout, false)
{
}
public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
{
this.port = port;
this.clientTimeout = clientTimeout;
this.useBufferedSockets = useBufferedSockets;
try
{
// Make server socket
this.server = TSocketVersionizer.CreateTcpListener(this.port);
this.server.Server.NoDelay = true;
}
catch (Exception)
{
server = null;
throw new TTransportException("Could not create ServerSocket on port " + this.port + ".");
}
}
public TServerSocket(int port, int clientTimeout, bool useBufferedSockets)
{
this.port = port;
this.clientTimeout = clientTimeout;
this.useBufferedSockets = useBufferedSockets;
try
{
// Make server socket
this.server = TSocketVersionizer.CreateTcpListener(this.port);
this.server.Server.NoDelay = true;
}
catch (Exception)
{
server = null;
throw new TTransportException("Could not create ServerSocket on port " + this.port + ".");
}
}
public override void Listen()
{
// Make sure not to block on accept
if (server != null)
{
try
{
server.Start();
}
catch (SocketException sx)
{
throw new TTransportException("Could not accept on listening socket: " + sx.Message);
}
}
}
public override void Listen()
{
// Make sure not to block on accept
if (server != null)
{
try
{
server.Start();
}
catch (SocketException sx)
{
throw new TTransportException("Could not accept on listening socket: " + sx.Message);
}
}
}
protected override TTransport AcceptImpl()
{
if (server == null)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
}
try
{
TSocket result2 = null;
TcpClient result = server.AcceptTcpClient();
try
{
result2 = new TSocket(result);
result2.Timeout = clientTimeout;
if (useBufferedSockets)
{
TBufferedTransport result3 = new TBufferedTransport(result2);
return result3;
}
else
{
return result2;
}
}
catch (System.Exception)
{
// If a TSocket was successfully created, then let
// it do proper cleanup of the TcpClient object.
if (result2 != null)
result2.Dispose();
else // Otherwise, clean it up ourselves.
((IDisposable)result).Dispose();
throw;
}
}
catch (Exception ex)
{
throw new TTransportException(ex.ToString());
}
}
protected override TTransport AcceptImpl()
{
if (server == null)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "No underlying server socket.");
}
try
{
TSocket result2 = null;
TcpClient result = server.AcceptTcpClient();
try
{
result2 = new TSocket(result);
result2.Timeout = clientTimeout;
if (useBufferedSockets)
{
TBufferedTransport result3 = new TBufferedTransport(result2);
return result3;
}
else
{
return result2;
}
}
catch (System.Exception)
{
// If a TSocket was successfully created, then let
// it do proper cleanup of the TcpClient object.
if (result2 != null)
result2.Dispose();
else // Otherwise, clean it up ourselves.
((IDisposable)result).Dispose();
throw;
}
}
catch (Exception ex)
{
throw new TTransportException(ex.ToString());
}
}
public override void Close()
{
if (server != null)
{
try
{
server.Stop();
}
catch (Exception ex)
{
throw new TTransportException("WARNING: Could not close server socket: " + ex);
}
server = null;
}
}
}
public override void Close()
{
if (server != null)
{
try
{
server.Stop();
}
catch (Exception ex)
{
throw new TTransportException("WARNING: Could not close server socket: " + ex);
}
server = null;
}
}
}
}

View File

@ -34,10 +34,11 @@ namespace Thrift.Transport
public TTransport Accept()
{
TTransport transport = AcceptImpl();
if (transport == null) {
throw new TTransportException("accept() may not return NULL");
if (transport == null)
{
throw new TTransportException("accept() may not return NULL");
}
return transport;
}
}
}
}

View File

@ -112,7 +112,7 @@ namespace Thrift.Transport
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");
}
@ -282,9 +282,9 @@ namespace Thrift.Transport
private volatile Boolean _isCompleted;
private ManualResetEvent _evt;
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;
_state = state;
@ -314,7 +314,7 @@ namespace Thrift.Transport
get { return _isCompleted; }
}
private readonly Object _locker = new Object();
private readonly object _locker = new object();
private ManualResetEvent GetEvtHandle()
{
@ -362,7 +362,7 @@ namespace Thrift.Transport
}
}
#region " IDisposable Support "
#region " IDisposable Support "
private bool _IsDisposed;
// IDisposable
@ -385,7 +385,7 @@ namespace Thrift.Transport
}
_IsDisposed = true;
}
#endregion
#endregion
}
}

View File

@ -26,216 +26,220 @@ using System.Net.Sockets;
namespace Thrift.Transport
{
public class TSocket : TStreamTransport
{
private TcpClient client = null;
private string host = null;
private int port = 0;
private int timeout = 0;
public class TSocket : TStreamTransport
{
private TcpClient client = null;
private string host = null;
private int port = 0;
private int timeout = 0;
public TSocket(TcpClient client)
{
this.client = client;
public TSocket(TcpClient client)
{
this.client = client;
if (IsOpen)
{
inputStream = client.GetStream();
outputStream = client.GetStream();
}
}
if (IsOpen)
{
inputStream = client.GetStream();
outputStream = client.GetStream();
}
}
public TSocket(string host, int port)
: this(host, port, 0)
{
}
public TSocket(string host, int port)
: this(host, port, 0)
{
}
public TSocket(string host, int port, int timeout)
{
this.host = host;
this.port = port;
this.timeout = timeout;
public TSocket(string host, int port, int timeout)
{
this.host = host;
this.port = port;
this.timeout = timeout;
InitSocket();
}
InitSocket();
}
private void InitSocket()
{
this.client = TSocketVersionizer.CreateTcpClient();
this.client.ReceiveTimeout = client.SendTimeout = timeout;
this.client.Client.NoDelay = true;
}
private void InitSocket()
{
this.client = TSocketVersionizer.CreateTcpClient();
this.client.ReceiveTimeout = client.SendTimeout = timeout;
this.client.Client.NoDelay = true;
}
public int Timeout
{
set
{
client.ReceiveTimeout = client.SendTimeout = timeout = value;
}
}
public int Timeout
{
set
{
client.ReceiveTimeout = client.SendTimeout = timeout = value;
}
}
public TcpClient TcpClient
{
get
{
return client;
}
}
public TcpClient TcpClient
{
get
{
return client;
}
}
public string Host
{
get
{
return host;
}
}
public string Host
{
get
{
return host;
}
}
public int Port
{
get
{
return port;
}
}
public int Port
{
get
{
return port;
}
}
public override bool IsOpen
{
get
{
if (client == null)
{
return false;
}
public override bool IsOpen
{
get
{
if (client == null)
{
return false;
}
return client.Connected;
}
}
return client.Connected;
}
}
public override void Open()
{
if (IsOpen)
{
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
}
public override void Open()
{
if (IsOpen)
{
throw new TTransportException(TTransportException.ExceptionType.AlreadyOpen, "Socket already connected");
}
if (String.IsNullOrEmpty(host))
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
}
if (string.IsNullOrEmpty(host))
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
}
if (port <= 0)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
}
if (port <= 0)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open without port");
}
if (client == null)
{
InitSocket();
}
if (client == null)
{
InitSocket();
}
if( timeout == 0) // no timeout -> infinite
{
client.Connect(host, port);
}
else // we have a timeout -> use it
{
ConnectHelper hlp = new ConnectHelper(client);
IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
if (!bConnected)
{
lock (hlp.Mutex)
{
if( hlp.CallbackDone)
{
asyncres.AsyncWaitHandle.Close();
client.Close();
}
else
{
hlp.DoCleanup = true;
client = null;
}
}
throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
}
}
if (timeout == 0) // no timeout -> infinite
{
client.Connect(host, port);
}
else // we have a timeout -> use it
{
ConnectHelper hlp = new ConnectHelper(client);
IAsyncResult asyncres = client.BeginConnect(host, port, new AsyncCallback(ConnectCallback), hlp);
bool bConnected = asyncres.AsyncWaitHandle.WaitOne(timeout) && client.Connected;
if (!bConnected)
{
lock (hlp.Mutex)
{
if (hlp.CallbackDone)
{
asyncres.AsyncWaitHandle.Close();
client.Close();
}
else
{
hlp.DoCleanup = true;
client = null;
}
}
throw new TTransportException(TTransportException.ExceptionType.TimedOut, "Connect timed out");
}
}
inputStream = client.GetStream();
outputStream = client.GetStream();
}
inputStream = client.GetStream();
outputStream = client.GetStream();
}
static void ConnectCallback(IAsyncResult asyncres)
{
ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
lock (hlp.Mutex)
{
hlp.CallbackDone = true;
static void ConnectCallback(IAsyncResult asyncres)
{
ConnectHelper hlp = asyncres.AsyncState as ConnectHelper;
lock (hlp.Mutex)
{
hlp.CallbackDone = true;
try
{
if( hlp.Client.Client != null)
hlp.Client.EndConnect(asyncres);
}
catch (Exception)
{
// catch that away
}
try
{
if (hlp.Client.Client != null)
hlp.Client.EndConnect(asyncres);
}
catch (Exception)
{
// catch that away
}
if (hlp.DoCleanup)
{
try {
asyncres.AsyncWaitHandle.Close();
} catch (Exception) {}
if (hlp.DoCleanup)
{
try
{
asyncres.AsyncWaitHandle.Close();
}
catch (Exception) { }
try {
if (hlp.Client is IDisposable)
((IDisposable)hlp.Client).Dispose();
} catch (Exception) {}
hlp.Client = null;
}
}
}
try
{
if (hlp.Client is IDisposable)
((IDisposable)hlp.Client).Dispose();
}
catch (Exception) { }
hlp.Client = null;
}
}
}
private class ConnectHelper
{
public object Mutex = new object();
public bool DoCleanup = false;
public bool CallbackDone = false;
public TcpClient Client;
public ConnectHelper(TcpClient client)
{
Client = client;
}
}
private class ConnectHelper
{
public object Mutex = new object();
public bool DoCleanup = false;
public bool CallbackDone = false;
public TcpClient Client;
public ConnectHelper(TcpClient client)
{
Client = client;
}
}
public override void Close()
{
base.Close();
if (client != null)
{
client.Close();
client = null;
}
}
public override void Close()
{
base.Close();
if (client != null)
{
client.Close();
client = null;
}
}
#region " IDisposable Support "
private bool _IsDisposed;
#region " IDisposable Support "
private bool _IsDisposed;
// IDisposable
protected override void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (client != null)
((IDisposable)client).Dispose();
base.Dispose(disposing);
}
}
_IsDisposed = true;
}
#endregion
}
// IDisposable
protected override void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (client != null)
((IDisposable)client).Dispose();
base.Dispose(disposing);
}
}
_IsDisposed = true;
}
#endregion
}
}

View File

@ -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.Linq;
using System.Net.Sockets;
@ -10,46 +33,46 @@ using System.Threading.Tasks;
namespace Thrift.Transport
{
/**
* 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.
* If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
*/
internal static class TSocketVersionizer
{
/*
* Creates a TcpClient according to the capabilitites of the used framework
*/
internal static TcpClient CreateTcpClient()
{
TcpClient client = null;
/// <summary>
/// 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.
/// If the DualMode is not available the system configuration determines whether IPv4 or IPv6 is used.
/// </summary>
internal static class TSocketVersionizer
{
/// <summary>
/// Creates a TcpClient according to the capabilitites of the used framework
/// </summary>
internal static TcpClient CreateTcpClient()
{
TcpClient client = null;
#if NET45
client = new TcpClient(AddressFamily.InterNetworkV6);
client.Client.DualMode = true;
client = new TcpClient(AddressFamily.InterNetworkV6);
client.Client.DualMode = true;
#else
client = new TcpClient(AddressFamily.InterNetwork);
#endif
return client;
}
return client;
}
/*
* Creates a TcpListener according to the capabilitites of the used framework
*/
internal static TcpListener CreateTcpListener(Int32 port)
{
TcpListener listener = null;
/// <summary>
/// Creates a TcpListener according to the capabilitites of the used framework.
/// </summary>
internal static TcpListener CreateTcpListener(Int32 port)
{
TcpListener listener = null;
#if NET45
listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
listener.Server.DualMode = true;
listener = new TcpListener(System.Net.IPAddress.IPv6Any, port);
listener.Server.DualMode = true;
#else
listener = new TcpListener(System.Net.IPAddress.Any, port);
listener = new TcpListener(System.Net.IPAddress.Any, port);
#endif
return listener;
}
}
}
}
}

View File

@ -105,24 +105,24 @@ namespace Thrift.Transport
}
#region " IDisposable Support "
private bool _IsDisposed;
#region " IDisposable Support "
private bool _IsDisposed;
// IDisposable
protected override void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
// IDisposable
protected override void Dispose(bool disposing)
{
if (InputStream != null)
InputStream.Dispose();
if (OutputStream != null)
OutputStream.Dispose();
if (!_IsDisposed)
{
if (disposing)
{
if (InputStream != null)
InputStream.Dispose();
if (OutputStream != null)
OutputStream.Dispose();
}
}
_IsDisposed = true;
}
}
_IsDisposed = true;
#endregion
}
#endregion
}
}

View File

@ -76,7 +76,7 @@ namespace Thrift.Transport
/// <param name="port">The port where the server runs.</param>
/// <param name="certificate">The certificate object.</param>
public TTLSServerSocket(int port, X509Certificate2 certificate)
: this(port, 0, certificate)
: this(port, 0, certificate)
{
}

View File

@ -263,7 +263,7 @@ namespace Thrift.Transport
/// <param name="sender">The sender-object.</param>
/// <param name="certificate">The used certificate.</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>
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");
}
if (String.IsNullOrEmpty(host))
if (string.IsNullOrEmpty(host))
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot open null host");
}
@ -307,7 +307,7 @@ namespace Thrift.Transport
{
RemoteCertificateValidationCallback validator = this.certValidator ?? DefaultCertificateValidator;
if( this.localCertificateSelectionCallback != null)
if (this.localCertificateSelectionCallback != null)
{
this.secureStream = new SslStream(
this.client.GetStream(),
@ -335,7 +335,7 @@ namespace Thrift.Transport
else
{
// 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);
}
}

View File

@ -53,7 +53,7 @@ namespace Thrift.Transport
if (bytes == 0)
return false;
}
catch( IOException)
catch (IOException)
{
return false;
}
@ -108,7 +108,7 @@ namespace Thrift.Transport
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);

View File

@ -26,7 +26,7 @@ using System;
namespace Thrift.Transport
{
/// <summary>
/// From Mark Slee & Aditya Agarwal of Facebook:
/// From Mark Slee &amp; Aditya Agarwal of Facebook:
/// Factory class used to create wrapped instance of Transports.
/// This is used primarily in servers, which get Transports from
/// a ServerTransport and then may want to mutate them (i.e. create