Как да внедря услуга C# Thrift и да я използвам с клиент Silverlight?

В момента разглеждам Thrift, който да използвам като RPC рамка за нашите приложения (предимно написани на C# и Silverlight). Стигнах дотам, че внедрявам услуга и я използвам от C# конзолно приложение (използвайки сокет като транспорт).

За кода от страна на сървъра на C# моят код изглеждаше така: (основно копиране на уроците, включени в изходния код)

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

За кода от страна на клиента изглеждаше така:

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

Ние обаче ще използваме услугата от клиент на Silverlight и за съжаление няма поддръжка за сокети в Silverlight for Thrift. Предполагам, че съм принуден да използвам HTTP комуникация между клиента и услугата, използвайки класовете C# THttpClient и THttpHandler на Thrift? Не можах да намеря никакви примери как да направя това там, може ли някой да ме насочи в правилната посока? Някои примерни сървърни и клиентски кодове ще бъдат оценени.


person Jaco Briers    schedule 30.01.2012    source източник
comment
Със Silverlight, и има много и разнообразни съображения за сигурност, моделът обикновено е да се извикват външни услуги от уеб хоста/услугата Silverlight или друга WCF или RIA услуга на вашия хостинг. Това означава, че вашето приложение Silverlight има един порт за повикване за всякакви услуги. Можете ли да предоставите примерен код?   -  person Gone Coding    schedule 30.01.2012
comment
Добавих примерен код   -  person Jaco Briers    schedule 30.01.2012
comment
как изглежда MyService?   -  person Chazt3n    schedule 19.08.2014


Отговори (2)


Изглежда, че този проблем вече е разгледан от това човек. Според този JIRA корекцията е налична в Thrift 0.9. Можете или да опитате тази моментна снимка (имайте предвид, че тъй като това не е окончателна версия, може да не е стабилен) или можете да приложите тази корекция до версия 0.8.

person npclaudiu    schedule 07.02.2012
comment
Благодаря, npclaudiu, вече използвам Thirft 0.9, който включва неговия пач, просто нямам представа как да го използвам; оттам и въпросът ми. - person Jaco Briers; 08.02.2012

Вярвам, че досега щяхте да разберете, че няма директен начин за комуникация от Silverlight към базата данни Cassandra, използвайки Thrift или други клиенти.

Имам една проста опция, свързана с това. Напишете уеб услуга с активиран Silverlight и я консумирайте от клиента.

Например, от страната на сървъра можете да имате уеб услуга, която прави вмъкване/актуализиране/четене и т.н., като това. Току-що успях да извадя някакъв код, който използваме за нашия проект. Надявам се това да помогне.

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;
        }


    }
}

Сега горният клас може да се използва от вашата уеб услуга, която от своя страна ще се използва от Silverlight. Между другото, ще трябва да се погрижите за други проблеми със silverlight като размера на данните за изтегляне от сървъра/уеб услугата и т.н., FYI, нашата клиентска услуга на Cassandra работи на порт 9160..

person Muthu    schedule 02.02.2012
comment
Здравей Muthu, писането на междинна уеб услуга не пречи ли на целта да напишеш оптимизирана Thrift услуга? Мисля, че трябва да е възможно да се комуникира с услугата Thrift чрез HTTP. - person Jaco Briers; 02.02.2012
comment
Не мисля така. Посочената от вас опция изглежда така, сякаш съм готов да дам клиентски скрипт като javascript, silverlight и т.н., за директен достъп до базата данни (може да е с цялата сигурност и т.н.). По-голямата част от базите данни не дават такъв директен достъп IMO. - person Muthu; 02.02.2012