示例#1
0
        protected override void OnMonitorReceive(IPAddress address, Guid guid, ushort channel, byte[] data)
        {
            Message.Base msg = ReceiveMonitorCommand(data);

            if (msg.IsType <Message.Negotiation.Channel.UDP>())
            {
                Message.Negotiation.Channel.UDP response = (Message.Negotiation.Channel.UDP)msg;

                ServerChannel channel_parameters = channels[response.channel];

                Message.Negotiation.Parameters param = new Message.Negotiation.Parameters
                {
                    guid          = response.guid,
                    channel       = response.channel,
                    type          = channel_parameters.type,
                    heartbeat     = channel_parameters.parameters.Heartbeat,
                    autoReconnect = !channel_parameters.parameters.disableAutoReconnect
                };

                Connection.Tcp monitor;

                if (monitors.TryGetValue(param.guid, out monitor))
                {
                    UdpConnectionParams udp_param = SendUdpParams(monitor, param);

                    ConnectUdp(udp_param, response);
                }
                else
                {
                    Debug.LogErrorFormat("No monitor channel with guid '{0}' to send UDP negotiation for channel {1}", param.guid, param.channel);
                }
            }
        }
示例#2
0
        protected void NegotiateChannels(Connection.Tcp connection)
        {
            Message.Base msg;

            if (connection.Receive(out msg))
            {
                if (msg.IsType <Message.Negotiation.Start>())
                {
                    connection.Parameters.guid = Guid.NewGuid();

                    SaveMonitor(connection);

                    // Send a new Guid for these connections and the number of associated channels
                    Message.Negotiation.New n = new Message.Negotiation.New
                    {
                        guid       = connection.Parameters.guid,
                        nbChannels = (ushort)Math.Min(channels != null ? channels.Count : 0, ushort.MaxValue)
                    };

                    connection.Send(n);

                    if (n.nbChannels <= 0)
                    {
                        Drop(connection, "No channels configured.");
                    }

                    for (ushort i = 0; i < n.nbChannels; i++)
                    {
                        ServerChannel channel = channels[i];

                        Message.Negotiation.Parameters param = new Message.Negotiation.Parameters
                        {
                            guid          = n.guid,
                            channel       = i,
                            type          = channel.type,
                            heartbeat     = channel.parameters.Heartbeat,
                            autoReconnect = !channel.parameters.disableAutoReconnect
                        };

                        connection.Send(param);
                    }
                }
                else if (msg.IsType <Message.Negotiation.Channel.TCP>())
                {
                    Message.Negotiation.Channel.TCP tcp = (Message.Negotiation.Channel.TCP)msg;

                    connection.SetConfig(tcp.guid, tcp.channel, channels[tcp.channel].parameters.Heartbeat);

                    SaveChannel(connection);
                }
                else
                {
                    Drop(connection, "Unsupported negotiation command '{0}'.", msg.GetType());
                }
            }
            else
            {
                Drop(connection, "Expected to receive some negotiation command.");
            }
        }
示例#3
0
        protected void AcceptClient(IAsyncResult async_result)
        {
            try
            {
                if (state == State.RUNNING && listener != null && listener.Server != null && listener.Server.IsBound)
                {
                    Message.Negotiation.Parameters param = new Message.Negotiation.Parameters
                    {
                        guid          = Guid.Empty,
                        channel       = ushort.MaxValue,
                        heartbeat     = negotiation.parameters.Heartbeat,
                        autoReconnect = !negotiation.parameters.disableAutoReconnect
                    };

                    // Get the new connection
                    Connection.Tcp connection = new Connection.Tcp(this, param, DisconnectionHandler, listener.EndAcceptTcpClient(async_result));

                    lock (initializedConnections)
                    {
                        initializedConnections.Add(connection);
                    }

                    connection.initialization = Task.Run(() => Connected(connection));
                }
            }
            catch (ObjectDisposedException)
            {
                // Can happen rarely because the atomicity between IsBound and EndAcceptTcpClient is not verified. Therefore the
                // listener can be disposed in this time frame. In this case, we have nothing to do. Just exit to close cleanly the listener.
            }
            catch (Exception exception)
            {
                Debug.LogErrorFormat("{0}: {1}\n{2}", exception.GetType(), exception.Message, exception.StackTrace);
            }
        }
示例#4
0
        protected void ConnectUdp(Connection.Tcp connection, Message.Negotiation.Parameters param)
        {
            UdpConnectionParams udp_params = SendUdpParams(connection, param);

            lock (pendingUdpConnection)
            {
                pendingUdpConnection.Add(udp_params);
            }
        }
示例#5
0
        protected void ConnectTcp(Message.Negotiation.Parameters param)
        {
            // Create a new TCP client
            Connection.Tcp connection = new Connection.Tcp(this, param, DisconnectionHandler, new TcpClient());

            if (param.guid != Guid.Empty)
            {
                lock (initializedConnections)
                {
                    initializedConnections.Add(connection);
                }
            }

            // Start asynchronous connection to server
            connection.initialization = Task.Run(() => connection.client.BeginConnect(hostname, port, Connected, connection));
        }
示例#6
0
        protected void NegotiateChannels(Connection.Tcp connection)
        {
            // Check if we must negotiate other channel or just open the current one
            if (connection.Remote == Guid.Empty)
            {
                connection.Send(new Message.Negotiation.Start());

                Message.Base msg;

                if (connection.Receive(out msg) && msg.IsType <Message.Negotiation.New>())
                {
                    Message.Negotiation.New n = (Message.Negotiation.New)msg;

                    connection.Parameters.guid = n.guid;

                    ushort nb_channels = n.nbChannels;

                    if (nb_channels > 0)
                    {
                        List <Message.Negotiation.Parameters> parameters = new List <Message.Negotiation.Parameters>(nb_channels);

                        for (ushort i = 0; i < nb_channels; i++)
                        {
                            if (connection.Receive(out msg) && msg.IsType <Message.Negotiation.Parameters>())
                            {
                                Message.Negotiation.Parameters param = (Message.Negotiation.Parameters)msg;

                                parameters.Add(param);
                            }
                            else
                            {
                                Drop(connection, "Expected to receive channel parameterts for channel {0}.", i);
                            }
                        }

                        SaveMonitor(connection);

                        foreach (Message.Negotiation.Parameters param in parameters)
                        {
                            if (!Ready(param.guid, param.channel))
                            {
                                switch (param.type)
                                {
                                case Channel.Type.TCP:
                                    ConnectTcp(param);
                                    break;

                                case Channel.Type.UDP:
                                    ConnectUdp(connection, param);
                                    break;
                                }
                            }
                        }

                        state = State.RUNNING;
                    }
                    else
                    {
                        Drop(connection, "No channels configured.");
                    }
                }
                else
                {
                    Drop(connection, "Expected to receive the new connection negotiation parameters.");
                }
            }
            else
            {
                Message.Negotiation.Channel.TCP tcp = new Message.Negotiation.Channel.TCP
                {
                    guid    = connection.Remote,
                    channel = connection.Channel
                };

                connection.Send(tcp);

                SaveChannel(connection);
            }
        }