Exemplo n.º 1
0
        private void Disconnect()
        {
            Debuger.Log(LOG_TAG_MAIN, "Disconnect()");

            KHDebugerGUI.RemoveDbgGUI("FSPClient");

            m_IsRunning = false;

            if (m_ThreadReceive != null)
            {
                m_ThreadReceive.Interrupt();
                m_ThreadReceive = null;
            }

            if (m_ThreadSend != null)
            {
                m_ThreadSend.Interrupt();
                m_ThreadSend = null;
            }

            if (m_Socket != null)
            {
                m_Socket.Close();
                m_Socket = null;
            }

            if (m_UseGSDK)
            {
                GSDKManager.Instance.EndSpeed();
            }

            m_HostEndPoint = null;
        }
Exemplo n.º 2
0
        private async Task ReconnectBroadcastListeningSocket()
        {
            var success = false;

            while (!success)
            {
                try
                {
                    var oldSocket = _BroadcastListenSocket;

                    _BroadcastListenSocket = null;
                    BeginListeningForBroadcasts();

                    try
                    {
                        oldSocket?.Dispose();
                    }
                    catch { }

                    success = true;
                    break;
                }
                catch
                {
                    await TaskEx.Delay(30000);
                }
            }
        }
Exemplo n.º 3
0
        private void ListenToSocket(IUdpSocket socket)
        {
            // Tasks are captured to local variables even if we don't use them just to avoid compiler warnings.
            var t = Task.Run(async() =>
            {
                var cancelled = false;
                while (!cancelled)
                {
                    try
                    {
                        var result = await socket.ReceiveAsync().ConfigureAwait(false);

                        if (result.ReceivedBytes > 0)
                        {
                            // Strange cannot convert compiler error here if I don't explicitly
                            // assign or cast to Action first. Assignment is easier to read,
                            // so went with that.
                            ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint, result.LocalIPAddress);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        cancelled = true;
                    }
                    catch (TaskCanceledException)
                    {
                        cancelled = true;
                    }
                }
            });
        }
Exemplo n.º 4
0
 public Connection(UdpRelay relay, IPEndPoint clientEP, IUdpSocket remoteUdp)
 {
     this.node      = new LinkedListNode <Connection>(this);
     this.relay     = relay;
     this.clientEP  = clientEP;
     this.remoteUdp = remoteUdp;
 }
Exemplo n.º 5
0
        private IUdpSocket CreateSocketAndListenForResponsesAsync()
        {
            _SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort);

            ListenToSocket(_SendSocket);

            return(_SendSocket);
        }
Exemplo n.º 6
0
        private async void ListenToSocket(IUdpSocket socket)
        {
            // Tasks are captured to local variables even if we don't use them just to avoid compiler warnings.
            try
            {
                await TaskEx.Run(async() =>
                {
                    var cancelled = false;
                    while (!cancelled)
                    {
                        try
                        {
                            var result = await socket.ReceiveAsync().ConfigureAwait(false);

                            if (result.ReceivedBytes > 0)
                            {
                                // Strange cannot convert compiler error here if I don't explicitly
                                // assign or cast to Action first. Assignment is easier to read,
                                // so went with that.
                                Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.ReceivedFrom);
                                var processTask    = TaskEx.Run(processWork);
                            }
                        }
                        catch (SocketClosedException)
                        {
                            if (this.IsDisposed)
                            {
                                return;                                              //No error or reconnect if we're shutdown.
                            }
                            await ReconnectBroadcastListeningSocket();
                            cancelled = true;
                            break;
                        }
                        catch (ObjectDisposedException)
                        {
                            cancelled = true;
                        }
                        catch (TaskCanceledException)
                        {
                            cancelled = true;
                        }
                    }
                });
            }
            catch
            {
                if (this.IsDisposed)
                {
                    return;
                }

                await ReconnectBroadcastListeningSocket();
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Causes the server to stop listening for multicast messages, being SSDP search requests and notifications.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void StopListeningForBroadcasts()
        {
            ThrowIfDisposed();

            lock ( _BroadcastListenSocketSynchroniser ) {
                if (_BroadcastListenSocket != null)
                {
                    _BroadcastListenSocket.Dispose();
                    _BroadcastListenSocket = null;
                }
            }
        }
Exemplo n.º 8
0
 private void EnsureSendSocketCreated()
 {
     if (_SendSocket == null)
     {
         lock (_SendSocketSynchroniser)
         {
             if (_SendSocket == null)
             {
                 _SendSocket = CreateSocketAndListenForResponsesAsync();
             }
         }
     }
 }
        internal DiscordVoiceAPIClient(DiscordSocketConfig config, ulong guildId, WebSocketProvider webSocketProvider, UdpSocketProvider udpSocketProvider, JsonSerializer serializer = null)
        {
            GuildId         = guildId;
            _connectionLock = new SemaphoreSlim(1, 1);
            _udp            = udpSocketProvider();
            Config          = config;

            _udp.ReceivedDatagram += async(data, index, count) =>
            {
                if (index != 0 || count != data.Length)
                {
                    byte[] newData = new byte[count];
                    Buffer.BlockCopy(data, index, newData, 0, count);
                    data = newData;
                }
                await _receivedPacketEvent.InvokeAsync(data).ConfigureAwait(false);
            };

            WebSocketClient = webSocketProvider();
            //_gatewayClient.SetHeader("user-agent", DiscordConfig.UserAgent); //(Causes issues in .Net 4.6+)

            WebSocketClient.BinaryMessage += async(data, index, count) =>
            {
                using (MemoryStream compressed = new MemoryStream(data, index + 2, count - 2))
                    using (MemoryStream decompressed = new MemoryStream())
                    {
                        using (DeflateStream zlib = new DeflateStream(compressed, CompressionMode.Decompress))
                            zlib.CopyTo(decompressed);
                        decompressed.Position = 0;
                        using (StreamReader reader = new StreamReader(decompressed))
                        {
                            SocketFrame msg = JsonConvert.DeserializeObject <SocketFrame>(reader.ReadToEnd());
                            await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
                        }
                    }
            };
            WebSocketClient.TextMessage += async text =>
            {
                SocketFrame msg = JsonConvert.DeserializeObject <SocketFrame>(text);
                await _receivedEvent.InvokeAsync((VoiceOpCode)msg.Operation, msg.Payload).ConfigureAwait(false);
            };
            WebSocketClient.Closed += async ex =>
            {
                await DisconnectAsync().ConfigureAwait(false);

                await _disconnectedEvent.InvokeAsync(ex).ConfigureAwait(false);
            };
            _serializer = serializer ?? new JsonSerializer {
                ContractResolver = new DiscordContractResolver()
            };
        }
Exemplo n.º 10
0
        /// <summary>
        /// Stops listening for search responses on the local, unicast socket.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void StopListeningForResponses()
        {
            ThrowIfDisposed();

            lock (_SendSocketSynchroniser)
            {
                var socket = _SendSocket;
                _SendSocket = null;
                if (socket != null)
                {
                    socket.Dispose();
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Causes the server to begin listening for multicast messages, being SSDP search requests and notifications.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void BeginListeningForBroadcasts()
        {
            ThrowIfDisposed();

            if (_BroadcastListenSocket == null)
            {
                lock ( _BroadcastListenSocketSynchroniser ) {
                    if (_BroadcastListenSocket == null)
                    {
                        _BroadcastListenSocket = ListenForBroadcastsAsync();
                    }
                }
            }
        }
Exemplo n.º 12
0
 private async Task SendFromSocket(IUdpSocket socket, byte[] messageData, IpEndPointInfo destination)
 {
     try
     {
         await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
     }
     catch (ObjectDisposedException)
     {
     }
     catch (Exception ex)
     {
         _logger.ErrorException("Error sending socket message from {0} to {1}", ex, socket.LocalIPAddress.ToString(), destination.ToString());
     }
 }
Exemplo n.º 13
0
        private async void UDPListen()
        {
            try {
                var anyEP  = new IPEndPoint(0, 0);
                var socket = new Socket(listen.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                socket.Bind(listen);
                udpClient = MyStream.FromSocket(socket);
                while (true)
                {
                    var r = await udpClient.ReadFromAsyncR(64 * 1024, anyEP);

                    Task.Run(() => HandleUdpReceiveResult(r)).Forget();
                }
            } catch (Exception e) {
                Logger.exception(e, Logging.Level.Warning, "UDP listener stopped");
            } finally {
                udpClient?.Close();
                udpClient = null;
            }
        }
Exemplo n.º 14
0
 public IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort)
 {
     return _MulticastSocket ?? (_MulticastSocket = new MockSocket(ipAddress, multicastTimeToLive, localPort));
 }
Exemplo n.º 15
0
 public IUdpSocket CreateUdpSocket(int localPort)
 {
     return _UnicastSocket ?? (_UnicastSocket = new MockSocket(localPort));
 }
Exemplo n.º 16
0
        /// <summary>
        /// Starts the specified port.
        /// </summary>
        /// <param name="port">The port.</param>
        public void Start(int port)
        {
            _udpClient = _socketFactory.CreateUdpSocket(port);

            Task.Run(() => StartListening());
        }
Exemplo n.º 17
0
        /// <summary>
        /// Causes the server to begin listening for multicast messages, being SSDP search requests and notifications.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void BeginListeningForBroadcasts()
        {
            ThrowIfDisposed();

            if (_BroadcastListenSocket == null)
            {
                lock (_BroadcastListenSocketSynchroniser)
                {
                    if (_BroadcastListenSocket == null)
                        _BroadcastListenSocket = ListenForBroadcastsAsync();
                }
            }
        }
Exemplo n.º 18
0
 protected override void OnStop()
 {
     base.OnStop();
     udpClient?.Close();
     udpClient = null;
 }
Exemplo n.º 19
0
        private void ListenToSocket(IUdpSocket socket)
        {
            // Tasks are captured to local variables even if we don't use them just to avoid compiler warnings.
            var t = TaskEx.Run(async () =>
            {

                var cancelled = false;
                while (!cancelled)
                {
                    try
                    {
                        var result = await socket.ReceiveAsync();

                        if (result.ReceivedBytes > 0)
                        {
                            // Strange cannot convert compiler error here if I don't explicitly
                            // assign or cast to Action first. Assignment is easier to read,
                            // so went with that.
                            Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.ReceivedFrom);
                            var processTask = TaskEx.Run(processWork);
                        }
                    }
                    catch (ObjectDisposedException)
                    {
                        cancelled = true;
                    }
                    catch (TaskCanceledException)
                    {
                        cancelled = true;
                    }
                }
            });
        }
Exemplo n.º 20
0
 public IUdpSocket CreateUdpSocket(int localPort)
 {
     return(_UnicastSocket ?? (_UnicastSocket = new MockSocket(localPort)));
 }
Exemplo n.º 21
0
        private IUdpSocket CreateSocketAndListenForResponsesAsync()
        {
            _SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort);

            ListenToSocket(_SendSocket);

            return _SendSocket;
        }
Exemplo n.º 22
0
        /// <summary>
        /// Stops listening for search responses on the local, unicast socket.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void StopListeningForResponses()
        {
            ThrowIfDisposed();

            lock (_SendSocketSynchroniser)
            {
                var socket = _SendSocket;
                _SendSocket = null;
                if (socket != null)
                    socket.Dispose();
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Causes the server to stop listening for multicast messages, being SSDP search requests and notifications.
        /// </summary>
        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
        public void StopListeningForBroadcasts()
        {
            ThrowIfDisposed();

            lock (_BroadcastListenSocketSynchroniser)
            {
                if (_BroadcastListenSocket != null)
                {
                    _BroadcastListenSocket.Dispose();
                    _BroadcastListenSocket = null;
                }
            }
        }
Exemplo n.º 24
0
 public IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort)
 {
     return(_MulticastSocket ?? (_MulticastSocket = new MockSocket(ipAddress, multicastTimeToLive, localPort)));
 }
Exemplo n.º 25
0
 private void EnsureSendSocketCreated()
 {
     if (_SendSocket == null)
     {
         lock (_SendSocketSynchroniser)
         {
             if (_SendSocket == null)
                 _SendSocket = CreateSocketAndListenForResponsesAsync();
         }
     }
 }
Exemplo n.º 26
0
        public bool Connect(string host, int port)
        {
            if (m_Socket != null)
            {
                Debuger.LogError(LOG_TAG_MAIN, "Connect() 无法建立连接,需要先关闭上一次连接!");
                return(false);
            }

            Debuger.Log(LOG_TAG_MAIN, "Connect() 建立基础连接, host = {0}, port = {1}", (object)host, port);

            m_Host = host;
            m_Port = port;

            try
            {
                //获取Host对应的IPEndPoint
                Debuger.Log(LOG_TAG_MAIN, "Connect() 获取Host对应的IPEndPoint");
                m_HostEndPoint = UdpSocket.GetHostEndPoint(m_Host, m_Port);
                if (m_HostEndPoint == null)
                {
                    Debuger.LogError(LOG_TAG_MAIN, "Connect() 无法将Host解析为IP!");
                    Close();
                    return(false);
                }
                Debuger.Log(LOG_TAG_MAIN, "Connect() HostEndPoint = {0}", m_HostEndPoint.ToString());

                m_IsRunning = true;

                //创建Socket
                Debuger.Log(LOG_TAG_MAIN, "Connect() 创建UdpSocket, AddressFamily = {0}", m_HostEndPoint.AddressFamily);
                m_Socket = CreateSocket(m_HostEndPoint.AddressFamily, m_Host, m_Port);

                if (m_UseGSDK)
                {
                    Debuger.Log(LOG_TAG_MAIN, "Connect() 启动GSDK加速!");
                    GSDKManager.Instance.StartSpeed(m_HostEndPoint.Address.ToString(), m_Host, m_Port);

                    GSDKManager.Instance.QueryNetwork(true, true, true);
                }

                //创建线程
                Debuger.Log(LOG_TAG_MAIN, "Connect() 创建接收线程");
                m_ThreadReceive = new Thread(Thread_Receive)
                {
                    IsBackground = true
                };
                m_ThreadReceive.Start();

                Debuger.Log(LOG_TAG_MAIN, "Connect() 创建发送线程");
                m_ThreadSend = new Thread(Thread_Send)
                {
                    IsBackground = true
                };
                m_ThreadSend.Start();
            }
            catch (Exception e)
            {
                Debuger.LogError(LOG_TAG_MAIN, "Connect() " + e.Message + e.StackTrace);
                Close();
                return(false);
            }


            //统计字段
            LastRemotePort   = port;
            LastRemoteHost   = host;
            LastRemoteHostIP = m_HostEndPoint.Address.ToString();


            //当用户直接用UnityEditor上的停止按钮退出游戏时,会来不及走完整的析构流程。
            //这里做一个监听保护
#if UNITY_EDITOR
            UnityEditor.EditorApplication.playmodeStateChanged -= OnEditorPlayModeChanged;
            UnityEditor.EditorApplication.playmodeStateChanged += OnEditorPlayModeChanged;
#endif
            KHDebugerGUI.AddDbgGUI("FSPClient", OnDbgGUI);

            return(true);
        }