示例#1
0
        public void Produce(string key, T value, long expireAt = long.MaxValue)
        {
            byte[] packet = LZ4MessagePackSerializer.Serialize(new Packet
            {
                Command  = "PUSH",
                Key      = key,
                Value    = LZ4MessagePackSerializer.Serialize(value),
                ExpireAt = expireAt
            });

            peer.Send(packet);
        }
示例#2
0
        public async Task Handle(BlockHeadersMessage message, IPeer sender)
        {
            var lastBlockHeaderIndex = _blockchain.LastBlockHeader.Index;
            var missingBlockHeaders  = (message.Payload.Headers ?? new BlockHeader[0])
                                       .Where(h => h != null && h.Index > lastBlockHeaderIndex)
                                       .Distinct(h => h.Index)
                                       .ToList();

            if (missingBlockHeaders.Count == 0)
            {
                return;
            }

            await _blockchain.AddBlockHeaders(missingBlockHeaders);

            // TODO: Find a better place for block sync

            var missingBlockHashes = missingBlockHeaders
                                     .Select(bh => bh.Hash)
                                     .Where(bh => bh != null)
                                     .ToList();

            await SynchronizeBlocks(missingBlockHashes, sender);

            if (_blockchain.LastBlockHeader.Index < sender.Version.CurrentBlockIndex)
            {
                _logger.LogInformation($"The peer has {sender.Version.CurrentBlockIndex + 1} blocks but the current number of block headers is {_blockchain.LastBlockHeader.Index + 1}.");
                await sender.Send(new GetBlockHeadersMessage(_blockchain.LastBlockHeader.Hash));
            }
        }
        /// <summary>
        /// 메세지를 브로드캐스팅 한다.
        /// </summary>
        /// <param name="accountId">계정</param>
        /// <param name="message">메세지</param>
        public void Broadcast(string accountId, string message)
        {
            cPKTSayNotify sendPacket = new cPKTSayNotify();

            sendPacket.AccountId = accountId;
            sendPacket.Message   = message;

            cLogger.Information("Broadcast AccountId: {0}, Message: {1}\r\n", accountId, message);

            StringBuilder log = new StringBuilder();

            foreach (KeyValuePair <string, IPeer> pair in PeerMap)
            {
                log.AppendFormat("AccountId: {0}, ", pair.Value.PeerId);
            }

            cLogger.Information("ChatRoom Member =====> {0}\r\n", log.ToString());

            Parallel.ForEach(PeerMap, pair =>
            {
                IPeer peer = pair.Value;
                if (null != peer)
                {
                    peer.Send(sendPacket);
                }
            });
        }
示例#4
0
        public void Execute(IPeer peer, IPacket packet)
        {
            cPKTChatLogin       recvPacket   = (cPKTChatLogin)packet;
            cPKTChatLoginResult resultPacket = new cPKTChatLoginResult();

            do
            {
                if (0 == recvPacket.AccountId.Length)
                {
                    resultPacket.ResultCode = cPKTChatLoginResult.eResultCode.TOO_SHORT_ACCOUNT_ID;
                    break;
                }

                cChatPlayer chatPlayer = (cChatPlayer)peer;
                chatPlayer.AccountId = recvPacket.AccountId;

                cLogger.Information("a peer is added (account_id: {0})\r\n", chatPlayer.AccountId);
                peer.PeerId = chatPlayer.AccountId;
                cPeerRegistry.Instance.Add(peer);

                cLogger.Information("join to chatroom (account_id: {0})\r\n", chatPlayer.AccountId);
                int retChatRoomNumber = cChatRoomManager.Join(recvPacket.AccountId, peer);

                resultPacket.ResultCode     = cPKTChatLoginResult.eResultCode.SUCCEED;
                resultPacket.ChatRoomNumber = retChatRoomNumber;
            } while (false);

            peer.Send(resultPacket);
        }
示例#5
0
        public void StartFor(IPeer peer, CancellationToken cancellationToken)
        {
            // Initiate handshake
            peer.Send(new VersionMessage(_serverContext.Version));

            Task.Factory.StartNew(async() =>
            {
                while (peer.IsConnected)
                {
                    var message = await peer.Receive();
                    if (message == null)
                    {
                        await _asyncDelayer.Delay(DefaultMessagePollingInterval, cancellationToken);
                        continue;
                    }

                    // TODO: Peer that sending wrong messages has to be disconnected.
                    if (peer.IsReady == message.IsHandshakeMessage())
                    {
                        continue;
                    }

                    await _messageHandler.Handle(message, peer);
                }
            }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }
示例#6
0
        /// <summary>
        /// Handle Inventory message
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="sender">Sender</param>
        /// <returns>Task</returns>
        public Task Handle(InventoryMessage message, IPeer sender)
        {
            var inventoryType = message.Payload.Type;

            if (Enum.IsDefined(typeof(InventoryType), inventoryType) == false)
            {
                _logger.LogError($"The payload of {nameof(InventoryMessage)} contains unknown {nameof(InventoryType)} \"{inventoryType}\".");

                return(Task.CompletedTask);
            }

            var hashes = message.Payload.Hashes
                         .Distinct()
                         .ToArray();

            // TODO: exclude known hashes

            if (!hashes.Any())
            {
                _logger.LogWarning($"The payload of {nameof(InventoryMessage)} contains no hashes.");

                return(Task.CompletedTask);
            }

            return(sender.Send(new GetDataMessage(inventoryType, hashes)));
        }
        public async Task Handle(GetBlockHashesMessage message, IPeer sender)
        {
            var blockHash = message.Payload.HashStart
                            .Select(p => _blockchain.GetBlockHeader(p))
                            .Where(p => p != null)
                            .OrderBy(p => p.Index)
                            .Select(p => p.Hash)
                            .FirstOrDefault();

            if (blockHash == null || blockHash == message.Payload.HashStop)
            {
                return;
            }

            var blockHashes = new List <UInt256>();

            do
            {
                blockHash = _blockchain.GetNextBlockHash(blockHash);

                if (blockHash == null || blockHash == message.Payload.HashStop)
                {
                    break;
                }

                blockHashes.Add(blockHash);
            } while (blockHash != message.Payload.HashStop && blockHashes.Count < MaxBlockHeadersCountToReturn);

            if (blockHashes.Count == 0)
            {
                return;
            }

            await sender.Send(new InventoryMessage(InventoryType.Block, blockHashes));
        }
        private async Task SendBlocks(IReadOnlyCollection <UInt256> blockHashes, IPeer peer)
        {
            var blocks = await _blockchain.GetBlocks(blockHashes);

            if (!blocks.Any())
            {
                return;
            }

            var filter = peer.BloomFilter;

            if (filter == null)
            {
                // TODO: The more efficient operation would be to send many blocks per one message
                // but it breaks backward compatibility
                await Task.WhenAll(blocks.Select(b => peer.Send(new BlockMessage(b))));
            }
            else
            {
                var merkleBlocks = blocks
                                   .ToDictionary(
                    b => b,
                    b => new BitArray(b.Transactions
                                      .Select(tx => TestFilter(filter, tx))
                                      .ToArray()
                                      )
                    );

                // TODO: Why don't we have this message?
                // await peer.Send(new MerkleBlockMessage(merkleBlocks));
            }
        }
示例#9
0
 private void Sync(IPeer peer = null)
 {
     Flush(actions =>
     {
         peer?.Send(new Packet(0, actions));
     });
 }
示例#10
0
        private async Task SendTransactions(IReadOnlyCollection <UInt256> transactionHashes, IPeer peer)
        {
            var transactions = await _blockchain.GetTransactions(transactionHashes);

            // TODO: The more efficient operation would be to send many transactions per one message
            // but it breaks backward compatibility
            await Task.WhenAll(transactions.Select(t => peer.Send(new TransactionMessage(t))));
        }
示例#11
0
        protected virtual void OnPeerJoinResponse(IPeer peer, JoinGroupResponse response)
        {
            GenericPacket packet = new GenericPacket();

            packet.InstCode = SimpleGameMetrics.OperationCode.Group;
            packet.Data     = response;
            byte[] dgram = serializer.Serialize(packet);
            peer.Send(dgram, Reliability.ReliableOrder);
        }
示例#12
0
        /// <inheritdoc />
        public override async Task Handle(MemPoolMessage message, IPeer sender)
        {
            var hashes = _transactionPool
                         .Take(InventoryPayload.MaxHashes)
                         .Select(tx => tx.Hash)
                         .ToArray();

            await sender.Send(new InventoryMessage(InventoryType.Transaction, hashes));
        }
示例#13
0
        /// <summary>
        /// Handle GetMemPool message
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="sender">Sender</param>
        /// <returns>Task</returns>
        public async Task Handle(MemPoolMessage message, IPeer sender)
        {
            var hashes = _blockchain.MemoryPool
                         .Peek(InventoryPayload.MaxHashes)
                         .Select(tx => tx.Value.Hash)
                         .ToArray();

            await sender.Send(new InventoryMessage(InventoryType.Transaction, hashes));
        }
示例#14
0
        public void Send(string message)
        {
            var buffer = _ToBytes(message);

            _Peer.Send(buffer, 0, buffer.Length).DoneEvent += (send_count) =>
            {
                _Viewer.WriteLine(string.Format("send bytes {0} ", send_count));
            };
        }
示例#15
0
    protected override void OnPeerJoinResponse(IPeer peer, JoinGroupResponse response)
    {
        GenericPacket packet = new GenericPacket();

        packet.InstCode = SimpleGameMetrics.OperationCode.Group;
        packet.Data     = response;
        peer.Send(serializer.Serialize(packet), Reliability.ReliableOrder);
        debugger.Log($"Send join response : peer[{peer.Id}] join group[{response.groupId}]");
    }
示例#16
0
        public async Task Handle(VerAckMessage message, IPeer sender)
        {
            sender.IsReady = true;

            if (_blockchain.LastBlockHeader.Index < sender.Version.CurrentBlockIndex)
            {
                _logger.LogInformation($"The peer has {sender.Version.CurrentBlockIndex + 1} blocks but the current number of block headers is {_blockchain.LastBlockHeader.Index + 1}.");
                await sender.Send(new GetBlockHeadersMessage(_blockchain.LastBlockHeader.Hash));
            }
        }
示例#17
0
        void IStage.Update()
        {
            if (_Counter.Second > _TimeToSend)
            {
                _Counter.Reset();

                var size = _Random.Next(_PackageSize);
                _Peer.Send(_CreateData(size), 0, size);
            }
        }
示例#18
0
        private static async Task SynchronizeBlocks(IReadOnlyCollection <UInt256> blockHashes, IPeer sender)
        {
            var batchesCount = blockHashes.Count / MaxBlocksCountToSync + (blockHashes.Count % MaxBlocksCountToSync != 0 ? 1 : 0);

            for (var i = 0; i < batchesCount; i++)
            {
                var blockHashesInBatch = blockHashes
                                         .Skip(i * MaxBlocksCountToSync)
                                         .Take(MaxBlocksCountToSync);

                await sender.Send(new GetDataMessage(InventoryType.Block, blockHashesInBatch));
            }
        }
        /// <inheritdoc />
        public override async Task Handle(BlockHeadersMessage message, IPeer sender)
        {
            message.Payload.Headers.ForEach(a => a.Type = HeaderType.Header);

            await _blockHeaderPersister.Persist(message.Payload.Headers ?? new BlockHeader[0]);

            if (_blockchainContext.LastBlockHeader.Index < sender.Version.CurrentBlockIndex)
            {
                _logger.LogInformation(
                    $"The peer has {sender.Version.CurrentBlockIndex + 1} blocks but the current number of block headers is {_blockchainContext.LastBlockHeader.Index + 1}.");
                await sender.Send(new GetBlockHeadersMessage(_blockchainContext.LastBlockHeader.Hash));
            }
        }
示例#20
0
        public async Task Handle(VersionMessage message, IPeer sender)
        {
            if (_server.Nonce != message.Payload.Nonce)
            {
                throw new InvalidOperationException("The handshake failed.");
            }

            if (_server.Version > message.Payload.Version)
            {
                _logger.LogWarning("Downgraded to lower protocol version.");
                sender.DowngradeProtocol(message.Payload.Version);
            }

            await sender.Send <VerAckMessage>();
        }
示例#21
0
        public async Task Handle(VersionMessage message, IPeer sender)
        {
            sender.Version = message.Payload;

            if (_server.Nonce == sender.Version.Nonce)
            {
                throw new InvalidOperationException($"The handshake is failed due to \"{nameof(_server.Nonce)}\" value equality.");
            }

            if (_server.ProtocolVersion > sender.Version.Version)
            {
                _logger.LogWarning("Downgraded to a lower protocol version.");
                sender.DowngradeProtocol(sender.Version.Version);
            }

            await sender.Send <VerAckMessage>();
        }
        /// <inheritdoc />
        public override async Task Handle(GetBlocksMessage message, IPeer sender)
        {
            var hashStart = (message.Payload.HashStart ?? new UInt256[0])
                            .Where(h => h != null)
                            .Distinct()
                            .ToArray();

            if (hashStart.Length == 0)
            {
                return;
            }

            var hashStop = message.Payload.HashStop;

            var blockHash = (await Task.WhenAll(hashStart.Select(GetBlockHeader)))
                            .Where(bh => bh != null)
                            .OrderBy(bh => bh.Index)
                            .Select(bh => bh.Hash)
                            .FirstOrDefault();

            if (blockHash == null || blockHash == hashStop)
            {
                return;
            }

            var blockHashes = new List <UInt256>();

            do
            {
                blockHash = await this._blockRepository.GetNextBlockHash(blockHash);

                if (blockHash == null || blockHash == hashStop)
                {
                    break;
                }

                blockHashes.Add(blockHash);
            } while (blockHashes.Count < MaxBlocksCountToReturn);

            if (blockHashes.Count == 0)
            {
                return;
            }

            await sender.Send(new InventoryMessage(InventoryType.Block, blockHashes));
        }
        public async Task Handle(GetBlockHeadersMessage message, IPeer sender)
        {
            var hashStart = (message.Payload.HashStart ?? new UInt256[0])
                            .Where(h => h != null)
                            .Distinct()
                            .ToArray();

            if (hashStart.Length == 0)
            {
                return;
            }

            var hashStop = message.Payload.HashStop;

            var blockHash = (await Task.WhenAll(hashStart.Select(GetBlockHeader)))
                            .Where(bh => bh != null)
                            .OrderBy(bh => bh.Index)
                            .Select(bh => bh.Hash)
                            .FirstOrDefault();

            if (blockHash == null || blockHash == hashStop)
            {
                return;
            }

            var blockHeaders = new List <BlockHeader>();

            do
            {
                blockHash = await _blockchain.GetNextBlockHash(blockHash);

                if (blockHash == null || blockHash == hashStop)
                {
                    break;
                }

                blockHeaders.Add(await _blockchain.GetBlockHeader(blockHash));
            } while (blockHeaders.Count < MaxBlockHeadersCountToReturn);

            if (blockHeaders.Count == 0)
            {
                return;
            }

            await sender.Send(new BlockHeadersMessage(blockHeaders));
        }
示例#24
0
        /// <inheritdoc />
        public override async Task Handle(VersionMessage message, IPeer sender)
        {
            sender.Version = message.Payload;
            if (_serverContext.Version.Nonce == sender.Version.Nonce)
            {
                throw new InvalidMessageException($"The handshake is failed due to \"{nameof(_serverContext.Version.Nonce)}\" value equality.");
            }

            // Change protocol?
            if (sender.ChangeProtocol(message.Payload))
            {
                _logger?.LogWarning("Changed protocol.");
            }

            // Send Ack
            await sender.Send <VerAckMessage>();
        }
        public void Execute(IPeer peer, IPacket packet)
        {
            cPKTSay       recvPacket = (cPKTSay)packet;
            cPKTSayResult sendPacket = new cPKTSayResult();

            sendPacket.Message = recvPacket.Message;

            if (true == cChatRoomManager.Broadcast(peer.PeerId, recvPacket.Message))
            {
                sendPacket.ResultCode = cPKTSayResult.eResultCode.SUCCEED;
            }
            else
            {
                sendPacket.ResultCode = cPKTSayResult.eResultCode.FAILURE;
            }

            peer.Send(sendPacket);
        }
        public void Execute(IPeer peer, IPacket packet)
        {
            cPKTChatRoomChange       recvPacket   = (cPKTChatRoomChange)packet;
            cPKTChatRoomChangeResult resultPacket = new cPKTChatRoomChangeResult();

            do
            {
                cChatPlayer chatPlayer = (cChatPlayer)peer;
                if (false == cChatRoomManager.ChangeChatRoom(chatPlayer.AccountId, recvPacket.NewChatRoomIndex))
                {
                    resultPacket.ResultCode = cPKTChatRoomChangeResult.eResultCode.CANNOT_CHANGE_CHAT_ROOM;
                    break;
                }

                resultPacket.ResultCode = cPKTChatRoomChangeResult.eResultCode.SUCCEED;
            } while (false);

            peer.Send(resultPacket);
        }
示例#27
0
        private void _Write(TPackage[] packages)
        {
            try
            {
                _Buffer = _CreateBuffer(packages);


                var task = _Peer.Send(_Buffer, 0, _Buffer.Length);
                task.DoneEvent += _WriteCompletion;
            }
            catch (SystemException e)
            {
                var info = string.Format("PackageWriter Error Write {0}.", _Peer.Connected);
                Singleton <Log> .Instance.WriteInfo(info);

                if (ErrorEvent != null)
                {
                    ErrorEvent();
                }
            }
        }
        /// <inheritdoc />
        public override async Task Handle(GetAddrMessage message, IPeer sender)
        {
            var peers = this._serverContext.ConnectedPeers.Values
                        .OrderBy(p => BitConverter.ToUInt32(Crypto.Default.GenerateRandomBytes(4), 0))
                        .Take(MaxCountToSend)
                        .ToArray();

            var networkAddressWithTimes = peers
                                          .Select(p => new NetworkAddressWithTime
            {
                EndPoint  = p.EndPoint.ToIpEndPoint(),
                Services  = p.Version.Services,
                Timestamp = p.Version.Timestamp
            }
                                                  )
                                          .ToArray();

            await sender.Send
            (
                new AddrMessage(networkAddressWithTimes)
            );
        }
示例#29
0
        private void PeerConnected(object sender, IPeer peer)
        {
            try
            {
                if (_acl != null && !_acl.IsAllowed(peer))
                {
                    throw new UnauthorizedAccessException();
                }

                this._connectedPeers.Add(peer);

                this.ListenForMessages(peer, this._messageListenerTokenSource.Token);

                // initiate handshake
                peer.Send(this.VersionMessage);
            }
            catch (Exception e)
            {
                this._logger.LogWarning($"Something went wrong with {peer}. Exception: {e}");
                peer.Disconnect();
            }
        }
        public async Task Handle(GetAddrMessage message, IPeer sender)
        {
            var rand  = new Random(Environment.TickCount);
            var peers = _server.ConnectedPeers
                        .OrderBy(p => rand.Next())
                        .Take(MaxCountToSend)
                        .ToArray();

            var networkAddressWithTimes = peers
                                          .Select(p => new NetworkAddressWithTime
            {
                EndPoint  = p.EndPoint.ToIpEndPoint(),
                Services  = p.Version.Services,
                Timestamp = p.Version.Timestamp
            }
                                                  )
                                          .ToArray();

            await sender.Send
            (
                new AddrMessage(networkAddressWithTimes)
            );
        }