public RpcAnswer RpcCall(Combinator combinator, params string[] expectedAnswers) { Trace.TraceInformation("#Send plain: {0}", combinator); var pm = new PlainMessage(0, combinator); var transport = new TcpTransport(_connection.PacketNumber++, pm.Serialize()); byte[] responseb = _connection.ExchangeWithServer(transport.Serialize()); TcpTransport answer; using (var ms = new MemoryStream(responseb)) answer = new TcpTransport(ms); uint constructor = PlainMessage.ExtractConstructor(answer.Payload); new Crc32(); foreach (string item in expectedAnswers) { uint crc32 = Crc32.Compute(Encoding.UTF8.GetBytes(item)); if (crc32 == constructor) { var resultCombinator = new PlainMessage(answer.Payload, item.Split(' ').Last().Trim()).Combinator; Trace.TraceInformation("#Recieve plain: {0}", resultCombinator); return new RpcAnswer(resultCombinator); } } throw new ArgumentException("unexpected answer"); }
private IEnumerable<SessionContainer> ExtractCombinators(TcpTransport item) { var results = new List<SessionContainer>(); // снимем шифрование var em = new EncryptedMessage(_settings.AuthKey, item.Payload); // если контейнер - вскроем его int crc32 = em.GetConstructorCrc(); // Если контейнер // Простой контейнер содержит несколько сообщений следующим образом: // msg_container#73f1f8dc messages:vector message = MessageContainer; // Здесь message обозначает любое сообщение вместе с длиной и с msg_id: // message msg_id:long seqno:int bytes:int body:Object = Message; if (crc32 == 0x73f1f8dc) { // Распарсим все входные ответы using (var data = new MemoryStream(em.Data.MessageData)) using (var br = new BinaryReader(data)) { br.ReadInt32(); // конструктор int count = br.ReadInt32(); // количество сообщений внутри for (int i = 0; i < count; i++) { br.ReadInt64(); br.ReadInt32(); int msgLength = br.ReadInt32(); byte[] msg = br.ReadBytes(msgLength); // Внутри конструктора ожидаются следующие системные типы //rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult; //rpc_error#2144ca19 error_code:int error_message:string = RpcError; //gzip_packed#3072cfa1 packed_data:string = Object; // msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck; // Сформируем инстанс комбинатора и внесем его в очередь var temp = new SessionContainer(em.Data.SessionId, msg); results.Add(temp); } } } else // простое сообщение { results.Add(new SessionContainer(em.Data.SessionId, em.Data.MessageData)); } return results; }
private IEnumerable<Combinator> Exchange(Combinator combinator) { _session.Salt = _settings.NonceNewNonceXor; var oc = new SessionContainer(_session.SessionId, combinator); EncryptedMessage encMessage = _session.PrepareRpcCall(oc); var call = new TcpTransport(_connection.PacketNumber++, encMessage.Serialize()); _connection.Write(call.Serialize()); Trace.TraceInformation("#Send: {0}", combinator); var buffer = _connection.Read(); if (buffer.Length == 0) throw new DecodeException("Response is empty"); var result = new List<Combinator>();// ReSharper disable once LoopCanBeConvertedToQuery foreach (SessionContainer container in ProcessInputBuffer(buffer)) { Combinator c = Unwrap(container.Combinator, container.SessionId, _session.SessionId, combinator.Descriptor.type); if (c != null) result.Add(c); } return result; }