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; }
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); } } }
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; } } }); }
public Connection(UdpRelay relay, IPEndPoint clientEP, IUdpSocket remoteUdp) { this.node = new LinkedListNode <Connection>(this); this.relay = relay; this.clientEP = clientEP; this.remoteUdp = remoteUdp; }
private IUdpSocket CreateSocketAndListenForResponsesAsync() { _SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort); ListenToSocket(_SendSocket); return(_SendSocket); }
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(); } }
/// <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; } } }
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() }; }
/// <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(); } } }
/// <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(); } } } }
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()); } }
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; } }
public IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { return _MulticastSocket ?? (_MulticastSocket = new MockSocket(ipAddress, multicastTimeToLive, localPort)); }
public IUdpSocket CreateUdpSocket(int localPort) { return _UnicastSocket ?? (_UnicastSocket = new MockSocket(localPort)); }
/// <summary> /// Starts the specified port. /// </summary> /// <param name="port">The port.</param> public void Start(int port) { _udpClient = _socketFactory.CreateUdpSocket(port); Task.Run(() => StartListening()); }
/// <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(); } } }
protected override void OnStop() { base.OnStop(); udpClient?.Close(); udpClient = null; }
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; } } }); }
public IUdpSocket CreateUdpSocket(int localPort) { return(_UnicastSocket ?? (_UnicastSocket = new MockSocket(localPort))); }
private IUdpSocket CreateSocketAndListenForResponsesAsync() { _SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort); ListenToSocket(_SendSocket); return _SendSocket; }
/// <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(); } }
/// <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; } } }
public IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { return(_MulticastSocket ?? (_MulticastSocket = new MockSocket(ipAddress, multicastTimeToLive, localPort))); }
private void EnsureSendSocketCreated() { if (_SendSocket == null) { lock (_SendSocketSynchroniser) { if (_SendSocket == null) _SendSocket = CreateSocketAndListenForResponsesAsync(); } } }
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); }