TLSharp/TLSharp.Core/Network/MtProtoPlainSender.cs

82 lines
2.6 KiB
C#
Raw Normal View History

2015-09-28 04:01:17 +02:00
using System;
using System.IO;
using System.Threading;
2015-09-28 04:01:17 +02:00
using System.Threading.Tasks;
namespace TLSharp.Core.Network
{
2016-04-18 12:50:57 +02:00
public class MtProtoPlainSender
{
private int _timeOffset;
private long _lastMessageId;
private readonly Random _random;
private readonly TcpTransport _transport;
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
public MtProtoPlainSender(TcpTransport transport)
{
_transport = transport;
_random = new Random();
2016-04-18 12:50:57 +02:00
}
2015-09-28 04:01:17 +02:00
public async Task Send(byte[] data, CancellationToken token)
2016-04-18 12:50:57 +02:00
{
token.ThrowIfCancellationRequested();
2016-04-18 12:50:57 +02:00
using (var memoryStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(memoryStream))
{
binaryWriter.Write((long)0);
binaryWriter.Write(GetNewMessageId());
binaryWriter.Write(data.Length);
binaryWriter.Write(data);
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
byte[] packet = memoryStream.ToArray();
2015-09-28 04:01:17 +02:00
await _transport.Send(packet, token).ConfigureAwait(false);
2016-04-18 12:50:57 +02:00
}
}
}
2015-09-28 04:01:17 +02:00
public async Task<byte[]> Receive(CancellationToken token)
2016-04-18 12:50:57 +02:00
{
token.ThrowIfCancellationRequested();
var result = await _transport.Receive(token).ConfigureAwait(false);
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
using (var memoryStream = new MemoryStream(result.Body))
{
using (BinaryReader binaryReader = new BinaryReader(memoryStream))
{
long authKeyid = binaryReader.ReadInt64();
long messageId = binaryReader.ReadInt64();
int messageLength = binaryReader.ReadInt32();
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
byte[] response = binaryReader.ReadBytes(messageLength);
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
return response;
}
}
}
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
private long GetNewMessageId()
{
long time = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds);
long newMessageId = ((time / 1000 + _timeOffset) << 32) |
2016-04-18 12:50:57 +02:00
((time % 1000) << 22) |
(_random.Next(524288) << 2); // 2^19
2016-04-18 12:50:57 +02:00
// [ unix timestamp : 32 bit] [ milliseconds : 10 bit ] [ buffer space : 1 bit ] [ random : 19 bit ] [ msg_id type : 2 bit ] = [ msg_id : 64 bit ]
2015-09-28 04:01:17 +02:00
if (_lastMessageId >= newMessageId)
2016-04-18 12:50:57 +02:00
{
newMessageId = _lastMessageId + 4;
2016-04-18 12:50:57 +02:00
}
2015-09-28 04:01:17 +02:00
_lastMessageId = newMessageId;
2016-04-18 12:50:57 +02:00
return newMessageId;
}
2015-09-28 04:01:17 +02:00
2016-04-18 12:50:57 +02:00
}
2015-09-28 04:01:17 +02:00
}