示例#1
0
        private void HandleMessageReceived(IPEndPoint receivedFrom, byte[] buffer, int numBytesReceived)
        {
            NetworkPeer peer = null;

            if (peersByEndpoint.TryGetValue(receivedFrom, out peer))
            {
                peer.HandleMessageReceived(buffer, numBytesReceived);
            }
            else
            {
                if (NeutrinoConfig.LogLevel == NeutrinoLogLevel.Debug)
                {
                    NeutrinoConfig.Log("Received from potentially new peer at " + receivedFrom);
                }
                List <NetworkMessage> initialMessages = new List <NetworkMessage>(msgFactory.Read(buffer, numBytesReceived));
                var connectMsg = initialMessages.FirstOrDefault <NetworkMessage>(x => (x is ConnectMessage));
                if (connectMsg == null)
                {
                    NeutrinoConfig.Log("Ignoring peer who didn't send a ConnectMessage with his initial traffic");
                }
                else
                {
                    var newPeer = NeutrinoConfig.CreatePeer();
                    newPeer.Init(this, serverSocket, receivedFrom.Address, receivedFrom.Port, ((ConnectMessage)connectMsg).Nickname);
                    peersByEndpoint[(IPEndPoint)receivedFrom] = newPeer;
                    endpointsByPeer[newPeer] = (IPEndPoint)receivedFrom;
                    if (OnPeerConnected != null)
                    {
                        OnPeerConnected(newPeer);
                    }
                    newPeer.HandleMessageReceived(buffer, numBytesReceived);
                }
            }
        }
示例#2
0
        public void HandleAckMessage(AckMessage ackMessage)
        {
            OutboundMessage outboundMessage = null;

            if (outboundMessagesBySequence.TryGetValue(ackMessage.AckedSequenceNumber, out outboundMessage))
            {
                outboundMessages.Remove(outboundMessage);
                outboundMessagesBySequence.Remove(ackMessage.AckedSequenceNumber);
                outboundMessagePool.Push(outboundMessage);
            }
            if (isResetPending && outboundMessages.FirstOrDefault(x => x.NeedsAck) == null)
            {
                if (IsVerbose)
                {
                    NeutrinoConfig.Log(node.Name + " drained all outbound - resetting sequence and sending queued");
                }
                isResetPending = false;
                nextSequence   = 0;
                foreach (byte[] buffer in pendingResetOutboundMessages)
                {
                    Enqueue(msgFactory.Read(buffer));
                }
                pendingResetOutboundMessages.Clear();
            }
        }
示例#3
0
 private void BuildInstances(params Assembly[] messageAssemblies)
 {
     BuildInstances(typeof(NetworkMessage).Assembly);
     foreach (Assembly a in messageAssemblies)
     {
         BuildInstances(a);
     }
     NeutrinoConfig.Log("Built " + messages.Count + " registered network messages");
 }
示例#4
0
 public void Dispose()
 {
     NeutrinoConfig.Log("Node shutting down...");
     if (serverSocket != null)
     {
         serverSocket.Close(1000);
         serverSocket = null;
         NeutrinoConfig.Log("Node shutdown");
     }
 }
示例#5
0
 internal void DisconnectPeer(NetworkPeer peer)
 {
     if (NeutrinoConfig.LogLevel == NeutrinoLogLevel.Debug)
     {
         NeutrinoConfig.Log("Peer disconnected: " + peer);
     }
     if (OnPeerDisconnected != null)
     {
         OnPeerDisconnected(peer);
     }
     peersByEndpoint.Remove(peer.Endpoint);
     endpointsByPeer.Remove(peer);
 }
示例#6
0
        public void Start()
        {
            NeutrinoConfig.Log("Node starting...");
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            if (ServerHostname == null)
            {
                serverSocket.Bind(new IPEndPoint(IPAddress.Any, ServerPort));
            }
            else
            {
                serverSocket.Bind(new IPEndPoint(IPAddress.Any, 0));
                var addresses = Dns.GetHostAddresses(ServerHostname);
                if (addresses == null || addresses.Length == 0)
                {
                    throw new ApplicationException("Unable to resolve server [" + ServerHostname + "]");
                }
                else
                {
                    IPAddress address = addresses.FirstOrDefault <IPAddress>(x => x.AddressFamily == AddressFamily.InterNetwork);
                    if (address == null)
                    {
                        address = addresses.FirstOrDefault <IPAddress>(x => x.AddressFamily == AddressFamily.InterNetworkV6);
                    }
                    if (address == null)
                    {
                        throw new ApplicationException("Unable to find an IP address for server [" + ServerHostname + "]");
                    }
                    var serverPeer = NeutrinoConfig.CreatePeer();
                    serverPeer.Init(this, serverSocket, address, ServerPort, "Server");
                    IPEndPoint serverEndpoint = new IPEndPoint(address, ServerPort);
                    peersByEndpoint[serverEndpoint] = serverPeer;
                    endpointsByPeer[serverPeer]     = serverEndpoint;
                    if (OnPeerConnected != null)
                    {
                        OnPeerConnected(serverPeer);
                    }

                    var connectMsg = msgFactory.Get <ConnectMessage>();
                    connectMsg.Nickname = localNickname;
                    SendToAll(connectMsg);
                }
            }
            var asyncResult = serverSocket.BeginReceiveFrom(receiveBuffer, 0, NeutrinoConfig.MaxMessageSize, SocketFlags.None, ref receivedEndPoint, new AsyncCallback(HandleMessageReceived), null);

            if (asyncResult.CompletedSynchronously)
            {
                HandleMessageReceived(asyncResult);
            }
            NeutrinoConfig.Log("Node started");
        }
示例#7
0
        internal void Update()
        {
            outboundQueue.Send();
            int ticksSinceActivity = Environment.TickCount - previousActivityTimeTicks;

            if (ticksSinceActivity >= NeutrinoConfig.PeerTimeoutMillis)
            {
                if (NeutrinoConfig.LogLevel == NeutrinoLogLevel.Debug)
                {
                    NeutrinoConfig.Log("Disconnecting peer " + this + " because of inactivity for " + ticksSinceActivity + " millis");
                }
                Disconnect();
            }
        }
示例#8
0
 public void Enqueue(NetworkMessage msg)
 {
     if (isResetPending && msg.IsGuaranteed)
     {
         if (IsVerbose)
         {
             NeutrinoConfig.Log(node.Name + " reset pending enqueuing for later: " + msg);
         }
         byte[] buffer = new byte[NeutrinoConfig.MaxMessageSize];
         msg.Write(buffer);
         pendingResetOutboundMessages.Add(buffer);
     }
     else
     {
         var outboundMessage = outboundMessagePool.Pop();
         Assign(msg, outboundMessage);
         outboundMessages.Add(outboundMessage);
     }
 }
示例#9
0
        private void BuildInstances(Assembly messageAssembly)
        {
            Type networkMsgType = typeof(NetworkMessage);

            foreach (Type t in messageAssembly.GetTypes())
            {
                if (t.IsSubclassOf(networkMsgType) && !messagesByType.ContainsKey(t))
                {
                    if (messages.Count == Byte.MaxValue)
                    {
                        throw new ApplicationException("The maximum number of network messages has been reached - you need to use fewer message types in this project");
                    }
                    var msg = (NetworkMessage)t.GetConstructor(Type.EmptyTypes).Invoke(Utility.emptyArgs);
                    msg.Id           = (byte)messages.Count;
                    messages[msg.Id] = msg;
                    messagesByType[msg.GetType()] = msg;
                    NeutrinoConfig.Log("Registered message type " + msg.GetType() + " as Id " + msg.Id);
                }
            }
        }
示例#10
0
 private void Assign(NetworkMessage msg, OutboundMessage target)
 {
     target.ContainedMessageType = msg.GetType();
     if (msg.IsGuaranteed)
     {
         target.SequenceNumber = nextSequence++;
         outboundMessagesBySequence[target.SequenceNumber] = target;
         msg.SequenceNumber = target.SequenceNumber;
     }
     target.PayloadLength     = msg.Write(target.Payload);
     target.NeedsAck          = msg.IsGuaranteed;
     target.PreviousSendTicks = Environment.TickCount - resendGuaranteedPeriodTicks - 1;
     if (!(msg is ResetNetworkIdsMessage) && nextSequence == maxGuaranteedBeforeReset)
     {
         if (IsVerbose)
         {
             NeutrinoConfig.Log(node.Name + " reached max sequence - resetting...");
         }
         Enqueue(msgFactory.Get <ResetNetworkIdsMessage>());
         isResetPending = true;
     }
 }