Как реализовать службу 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-связь между клиентом и службой, используя классы Thrift C # THttpClient и THttpHandler? Я не мог найти никаких примеров того, как это сделать, может ли кто-нибудь указать мне в правильном направлении? Некоторые примеры кода на стороне сервера и клиента будут оценены.


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, таких как размер данных, которые будут загружены с сервера / веб-службы и т. Д., К вашему сведению, наша клиентская служба Cassandra работает на порту 9160 ..

person Muthu    schedule 02.02.2012
comment
Привет, Мутху, не побеждает ли написание промежуточного веб-сервиса задачу написания оптимизированного сервиса Thrift? Я думаю, что должна быть возможность общаться со службой Thrift через HTTP. - person Jaco Briers; 02.02.2012
comment
Я так не думаю. Указанный вами вариант выглядит так, как будто я готов предоставить клиентский скрипт, такой как javascript, silverlight и т. Д., Для прямого доступа к базе данных (может быть, со всей безопасностью и т. Д.). Большинство баз данных не предоставляют такой прямой доступ IMO. - person Muthu; 02.02.2012