2012-01-30 16 views
5

Actualmente estoy buscando en Thrift para usar como un marco de RPC para nuestras aplicaciones (principalmente escrito en C# y Silverlight). Llegué a implementar un servicio y consumirlo desde una aplicación de consola C# (usando un socket como transporte).¿Cómo implemento un servicio C# Thrift y lo consumo con un cliente de Silverlight?

Para el C# código del lado del servidor de mi código parecía: (básicamente copiar los tutoriales incluidos con el código fuente)

MyServiceHandler handler = new MyServiceHandler(); 
MyService.Processor processor = new MyService.Processor(handler); 
TServerTransport serverTransport = new TServerSocket(9090); 
TServer server = new TSimpleServer(processor, serverTransport); 
server.Serve(); 

Para el código del lado del cliente que parecía:

TTransport transport = new TSocket("localhost", 9090); 
TProtocol protocol = new TBinaryProtocol(transport); 
MyService.Client client = new MyService.Client(protocol); 
transport.Open(); 
client.SomeServiceCall(); 

Sin embargo , consumiremos el servicio de un cliente de Silverlight y, desafortunadamente, no hay soporte para sockets en Silverlight for Thrift. Supongo que me veo forzado a usar la comunicación HTTP entre el cliente y el servicio, usando las clases ThrowClip de Thrift y THttpHandler. No pude encontrar ningún ejemplo de cómo hacer esto, ¿puede alguien señalarme en la dirección correcta? Algún ejemplo de servidor y código del lado del cliente sería apreciado.

+0

Con Silverlight, * y sus muchas y variadas consideraciones de seguridad *, el patrón generalmente es llamar a servicios externos desde el servidor/servicio web de Silverlight u otro servicio WCF o RIA en su hosting. Esto significa que su aplicación Silverlight tiene un único puerto de escala para cualquier servicio. ¿Puedes proporcionar algún código de muestra? –

+0

Agregué un código de muestra –

+0

¿Cómo es MyService? – Chazt3n

Respuesta

0

Creo que a estas alturas ya habrías entendido que no hay una forma directa de comunicación entre Silverlight y la base de datos de Cassandra, ya sea utilizando Thrift o cualquier otro cliente.

Tengo una opción simple relacionada con esto. Escribir un servicio web habilitado para Silverlight y consumirlo del cliente.

Por ejemplo, en el lado del servidor puede tener un servicio web que inserta/actualiza/lee, etc., así. Solo logré sacar algún código que usamos para nuestro proyecto. Espero que esto ayude.

using Apache.Cassandra; 
using Thrift.Protocol; 
using Thrift.Transport; 

namespace CassandraWebLibrary 
{ 
    public class MyDb 
    { 
     String _host; 
     int _port; 
     String _keyspace; 
     bool _isConnected; 
     TTransport _transport = null; 
     Apache.Cassandra.Cassandra.Client _client = null; 
     String columnFamily = "ColumnFamilyName"; 
     public VazhikaattiDB(String host, int port, String keyspace) 
     { 
      _host = host; 
      _port = port; 
      _keyspace = keyspace; 
      _isConnected = false; 
     } 

     public bool Connect() 
     { 
      try 
      { 
       _transport = new TFramedTransport(new TSocket(_host, _port)); 
       TProtocol protocol = new TBinaryProtocol(_transport); 
       _client = new Apache.Cassandra.Cassandra.Client(protocol); 

       _transport.Open(); 

       _client.set_keyspace(_keyspace); 

       _isConnected = true; 
      } 
      catch (Exception ex) 
      { 
       log.Error(ex.ToString()); 
      } 
      return _isConnected; 
     } 

     public bool Close() 
     { 
      if (_transport.IsOpen) 
       _transport.Close(); 
      _isConnected = false; 
      return true; 
     } 

     public bool InsertData(Send your data as parameters here) 
     { 
      try 
      { 
       List<Column> list = new List<Column>(); 
       string strKey = keyvalue; 

       #region Inserting into Coulmn family 
       List<Byte> valbytes = new List<byte>(BitConverter.GetBytes(value)); //You might have to pad this with more bytes to make it length of 8 bytes 

       Column doublecolumn1 = new Column() 
       { 
        Name = Encoding.UTF8.GetBytes("column1"), 
        Timestamp = timestampvalue, 
        Value = valbytes.ToArray() 
       }; 
       list.Add(doublecolumn1); 

       Column stringcolumn2 = new Column() 
       { 
        Name = Encoding.UTF8.GetBytes("column2"), 
        Timestamp = timestampvalue, 
        Value = Encoding.UTF8.GetBytes("StringValue") 
       }; 
       list.Add(stringcolumn2); 

       Column timecolumn3 = new Column() 
       { 
        Name = Encoding.UTF8.GetBytes("column3"), 
        Timestamp = timestampvalue, 
        Value = BitConverter.GetBytes(DateTime.Now.Ticks) 
       }; 
       list.Add(timecolumn3); 
       #endregion 


       ColumnParent columnParent = new ColumnParent(); 
       columnParent.Column_family = columnFamily; 

       Byte[] key = Encoding.UTF8.GetBytes(strKey); 
       foreach (Column column in list) 
       { 
        try 
        { 
         _client.insert(key, columnParent, column, ConsistencyLevel.QUORUM); 
        } 
        catch (Exception e) 
        { 
         log.Error(e.ToString()); 
        } 
       } 

       return true; 
      } 
      catch (Exception ex) 
      { 
       log.Error(ex.ToString()); 
       return false; 
      } 
     } 

     public List<YourReturnObject> GetData(parameters) 
     { 
      try 
      { 
       ColumnParent columnParent = new ColumnParent(); 
       columnParent.Column_family = columnFamily; 
       DateTime curdate = startdate; 

       IndexExpression indExprsecondkey = new IndexExpression(); 
       indExprsecondkey.Column_name = Encoding.UTF8.GetBytes("column"); 
       indExprsecondkey.Op = IndexOperator.EQ; 

       List<Byte> valbytes = PadLeftBytes((int)yourid, 8); 
       indExprsecondkey.Value = valbytes.ToArray(); 
       indExprList.Add(indExprsecondkey); 


       IndexClause indClause = new IndexClause() 
       { 
        Expressions = indExprList, 
        Count = 1000, 
        Start_key = Encoding.UTF8.GetBytes("") 
       }; 

       SlicePredicate slice = new SlicePredicate() 
       { 
        Slice_range = new SliceRange() 
        { 
         //Start and Finish cannot be null 
         Start = new byte[0], 
         Finish = new byte[0], 
         Count = 1000, 
         Reversed = false 
        } 
       }; 
       List<KeySlice> keyslices = _client.get_indexed_slices(columnParent, indClause, slice, ConsistencyLevel.ONE); 
       foreach (KeySlice ks in keyslices) 
       { 
        String stringcolumnvalue = Encoding.UTF8.GetString(cl.Column.Value); 
        double doublevalue= (Double)BitConverter.ToDouble(cl.Column.Value); 
        long timeticks = BitConverter.ToInt64(cl.Column.Value, 0); 
        DateTime dtcolumntime = new DateTime(timeticks); 
       } 
      } 
      catch (Exception ex) 
      { 
       log.Error(ex.ToString()); 
      } 

      return yourdatalist; 
     } 


    } 
} 

Ahora la clase anterior puede ser utilizada por su servicio web, que a su vez será utilizado por Silverlight. Por cierto, tendrá que encargarse de otros problemas de Silverlight como el tamaño de los datos que se descargarán del servidor/servicio web, etc., FYI, nuestro servicio al cliente de Cassandra se ejecuta en el puerto 9160 ..

+0

Hola, Muthu, ¿no está escribiendo un servicio web intermedio para evitar el objetivo de escribir un servicio Thrift optimizado? Mi opinión es que debería ser posible comunicarse con el servicio Thrift a través de HTTP. –

+0

No lo creo. La opción especificada por usted parece como si estuviera listo para dar un script de cliente como javascript, silverlight, etc., para acceder directamente a la base de datos (puede ser con toda seguridad, etc.). La mayoría de las bases de datos no dan acceso directo a la OMI. – Muthu

1

Parece que este problema ya fue abordado por this guy. De acuerdo con this JIRA, la solución está disponible en Thrift 0.9. Puede probar this snapshot (tenga en cuenta que, como no es una versión final, puede que no sea estable) o puede aplicar this patch a la versión 0.8.

+0

Gracias npclaudiu, ya estoy haciendo uso de Thirft 0.9 que tiene su parche incluido, simplemente no tengo ni idea de cómo usarlo; de ahí mi pregunta. –

Cuestiones relacionadas