예제 #1
0
        /// <summary>
        /// Enqueues message in sending queue, uses own implementation of <see cref="RTransactionGenerator"/> if qosType is reliable.
        /// </summary>
        /// <param name="messageId"></param>
        /// <param name="data"></param>
        /// <param name="remoteEndPoint"></param>
        /// <param name="qosType"></param>
        public void Send(ref byte[] data, IPEndPoint remoteEndPoint, RQoSType qosType = RQoSType.Unrealiable)
        {
            if (data.Length == 0)
            {
                _logger?.WriteError(new LogInfo("Tried to send empty message."));
                return;
            }
            else if (remoteEndPoint == null)
            {
                _logger?.WriteError(new LogInfo("Could not send message to unknown endpoint."));
                return;
            }

            if (!_cts.Token.IsCancellationRequested)
            {
                RNetMessage message;
                switch (qosType)
                {
                default:
                case RQoSType.Realiable:
                case RQoSType.Internal:
                    message = new RNetMessage(data, RTransactionGenerator.GenerateId(), remoteEndPoint, qosType);
                    break;

                case RQoSType.Unrealiable:
                    message = new RNetMessage(data, null, remoteEndPoint, qosType);
                    break;
                }
                _outgoingMsgQueue.Enqueue(message);
            }
        }
예제 #2
0
        /// <summary>
        /// Sends disconnect message
        /// </summary>
        private void SendDisconnect()
        {
            DisconnectTransation = RTransactionGenerator.GenerateId();
            RNetMessage disc = new RNetMessage(Encoding.UTF8.GetBytes("disconnect_request"), DisconnectTransation, RemoteEndPoint, RQoSType.Internal);

            _outgoingMsgQueue.Enqueue(disc);
        }
예제 #3
0
        protected void HandleIncommingMessages(RNetMessage netMsg)
        {
            if (netMsg.QoSType != RQoSType.Unrealiable && netMsg.TransactionId != null)
            {
                if (_lastMessagesReceived.Contains(netMsg.TransactionId.Value))
                {
                    _logger?.WriteInfo(new LogInfo("skipping already received message " + netMsg.TransactionId.Value + "  " + BitConverter.ToInt32(netMsg.Data, 0)));
                    return;
                }
                _lastMessagesReceived.Add(netMsg.TransactionId.Value);
                if (_lastMessagesReceived.Count > _settings.StoreLastMessages)
                {
                    _lastMessagesReceived.RemoveAt(0);
                }
            }

            if (netMsg.QoSType == RQoSType.Internal)
            {
                OnReceiveInternalData?.Invoke(netMsg);
            }
            else
            {
                OnReceiveData?.Invoke(netMsg.Data, (IPEndPoint)netMsg.RemoteEndPoint);
            }
        }
예제 #4
0
 public void DisconnectEndPoint(IPEndPoint ep)
 {
     if (!_pendingDisconnects.ContainsKey(ep))
     {
         RNetMessage disc = new RNetMessage(Encoding.UTF8.GetBytes("disconnect_request"), RTransactionGenerator.GenerateId(), ep, RQoSType.Internal);
         _pendingDisconnects.Add(ep, DateTime.Now);
         _outgoingMsgQueue.Enqueue(disc);
     }
 }
예제 #5
0
        /// <summary>
        /// Sends Discover Message
        /// </summary>
        private void SendHello()
        {
            DiscoverTransaction = RTransactionGenerator.GenerateId();

            Error += OnDiscoverFailed;

            RNetMessage discover = new RNetMessage(Encoding.UTF8.GetBytes("discover"), DiscoverTransaction, RemoteEndPoint, RQoSType.Internal);

            _outgoingMsgQueue.Enqueue(discover);
        }
예제 #6
0
        /// <summary>
        /// Discover-Answer arrived
        /// </summary>
        /// <param name="message"></param>
        private void OnInternalMessage(RNetMessage message)
        {
            if (message.RemoteEndPoint != RemoteEndPoint)
            {
                //not the server...
                return;
            }

            string type = "discover";

            try
            {
                type = Encoding.UTF8.GetString(message.Data);
            }
            catch
            {
                //Encoding error
                return;
            }

            if (type.Equals("disconnect_response") && IsConnected && DisconnectTransation == message.TransactionId)
            {
                //Disconnect answer from server - Action invoked in Disconnect-Method
                _logger?.WriteInfo(new LogInfo("Disconnect successful"));
                IsConnected          = false;
                DisconnectTransation = null;
            }
            else if (type.Equals("disconnect_request") && IsConnected)
            {
                //Server requests a disconnect -> anwser confirm
                RNetMessage answer = new RNetMessage(Encoding.UTF8.GetBytes("disconnect_response"), message.TransactionId, RemoteEndPoint, RQoSType.Internal);
                _logger?.WriteInfo(new LogInfo("Disconnect by server"));

                IsConnected          = false;
                DisconnectTransation = null;
                FireDisconnectAction = true; //Invoke action in Dispatch-method (on main thread)
            }
            else if (type.Equals("discover") && !IsConnected && DiscoverTransaction == message.TransactionId)
            {
                //Discover answer from server
                _logger?.WriteInfo(new LogInfo("Connection successful"));
                IsConnected         = true;
                DiscoverTransaction = null;
                Error -= OnDiscoverFailed; //Clear all discover-fails

                Connected?.Invoke();
            }
        }
예제 #7
0
        private void OnInternalMessage(RNetMessage message)
        {
            string type = "discover";

            try
            {
                type = Encoding.UTF8.GetString(message.Data);
            }
            catch
            {
            }

            RNetMessage?discover = null;

            if (type.Equals("disconnect_request"))
            {
                //Client requests disconnect - send response
                _logger?.WriteInfo(new LogInfo("Connection closed by " + message.RemoteEndPoint.ToString()));
                discover = new RNetMessage(Encoding.UTF8.GetBytes("disconnect_response"), message.TransactionId, message.RemoteEndPoint, RQoSType.Internal);
                ClientDisconnected?.Invoke((IPEndPoint)message.RemoteEndPoint, true);
            }
            else if (type.Equals("disconnect_response"))
            {
                //Client answers for requested disconnect
                if (_pendingDisconnects.ContainsKey(message.RemoteEndPoint))
                {
                    _logger?.WriteInfo(new LogInfo("Connection to " + message.RemoteEndPoint + " closed by server"));
                    _pendingDisconnects.Remove(message.RemoteEndPoint);
                    ClientDisconnected?.Invoke((IPEndPoint)message.RemoteEndPoint, false);
                }
            }
            else if (type.Equals("discover"))
            {
                _logger?.WriteInfo(new LogInfo("Incomming connection from " + message.RemoteEndPoint.ToString()));
                ClientDiscoverMessage?.Invoke((IPEndPoint)message.RemoteEndPoint);
                discover = new RNetMessage(Encoding.UTF8.GetBytes("discover"), message.TransactionId, message.RemoteEndPoint, RQoSType.Internal);
            }

            if (discover != null)
            {
                _outgoingMsgQueue.Enqueue(discover);
            }
        }