void HandleClientDisconnected(object sender, ClientEventArgs <byte, byte> args) { var client = clients [args.Client]; clients.Remove(args.Client); EventHandlerExtensions.Invoke(OnClientDisconnected, this, new ClientDisconnectedEventArgs <NoMessage, StreamMessage> (client)); }
public void OnceFailsWithNullHandler() { var e = Assert.Throws <ArgumentNullException>(() => EventHandlerExtensions.Once(null, delegate { }, delegate { })); Assert.Equal("handler", e.ParamName); }
public void Should_get_all_handled_events_form_interface() { var supportedEvents = EventHandlerExtensions.GetEventTypesWhichHandlerSupports <IEventHandler <EventB> >(); supportedEvents.Should().HaveCount(1); supportedEvents.Should().Contain(typeof(EventB)); }
public void Stop() { if (!running) { return; } Logger.WriteLine("TCPServer: stop requested", Logger.Severity.Debug); tcpListener.Stop(); if (!listenerThread.Join(3000)) { throw new ServerException("Failed to stop TCP listener thread (timed out after 3 seconds)"); } // Close all client connections foreach (var client in pendingClients) { Logger.WriteLine("TCPServer: cancelling pending connection to client (" + client.Address + ")", Logger.Severity.Debug); DisconnectClient(client, true); } foreach (var client in clients) { Logger.WriteLine("TCPServer: closing connection to client (" + client.Address + ")", Logger.Severity.Debug); DisconnectClient(client); } pendingClients.Clear(); clients.Clear(); // Exited cleanly running = false; Logger.WriteLine("TCPServer: stopped successfully", Logger.Severity.Debug); EventHandlerExtensions.Invoke(OnStopped, this); }
public void Start() { if (OnClientRequestingConnection == null) { throw new ServerException("Client request handler not set"); } if (Running) { Logger.WriteLine("SerialIO.Server: start requested, but server is already running", Logger.Severity.Warning); return; } Logger.WriteLine("SerialIO.Server: starting " + Address, Logger.Severity.Debug); port = new SerialPort(Address, (int)BaudRate, Parity, DataBits, StopBits); Logger.WriteLine("SerialIO.Server: port name = " + Address, Logger.Severity.Debug); Logger.WriteLine("SerialIO.Server: baud rate = " + port.BaudRate, Logger.Severity.Debug); Logger.WriteLine("SerialIO.Server: data bits = " + port.DataBits, Logger.Severity.Debug); Logger.WriteLine("SerialIO.Server: parity = " + port.Parity, Logger.Severity.Debug); Logger.WriteLine("SerialIO.Server: stop bits = " + port.StopBits, Logger.Severity.Debug); try { port.Open(); } catch (Exception exn) { Close(); Logger.WriteLine("SerialIO.Server: failed to start server; " + exn, Logger.Severity.Error); throw new ServerException(exn.GetType() + ": " + exn.Message, exn); } // Discard stale data from the port port.DiscardInBuffer(); Logger.WriteLine("SerialIO.Server: started successfully", Logger.Severity.Debug); EventHandlerExtensions.Invoke(OnStarted, this); }
void HandleClientConnected(object sender, ClientEventArgs <byte, byte> args) { // Note: pendingClients and clients dictionaries are updated from HandleClientRequestingConnection var client = clients [args.Client]; EventHandlerExtensions.Invoke(OnClientConnected, this, new ClientConnectedEventArgs <Request, Response> (client)); }
internal Server(IServer <Request, Response> rpcServer, IServer <NoMessage, StreamMessage> streamServer) { Core.Instance.Add(this); RPCServer = rpcServer; StreamServer = streamServer; // Tie events to underlying server RPCServer.OnStarted += (s, e) => EventHandlerExtensions.Invoke(OnStarted, this); RPCServer.OnStopped += (s, e) => EventHandlerExtensions.Invoke(OnStopped, this); RPCServer.OnClientRequestingConnection += (s, e) => EventHandlerExtensions.Invoke(OnClientRequestingConnection, s, e); RPCServer.OnClientConnected += (s, e) => EventHandlerExtensions.Invoke(OnClientConnected, s, new ClientConnectedEventArgs(e.Client)); RPCServer.OnClientDisconnected += (s, e) => EventHandlerExtensions.Invoke(OnClientDisconnected, s, new ClientDisconnectedEventArgs(e.Client)); // Add/remove clients from the scheduler RPCServer.OnClientConnected += (s, e) => Core.Instance.RPCClientConnected(e.Client); RPCServer.OnClientDisconnected += (s, e) => Core.Instance.RPCClientDisconnected(e.Client); // Add/remove clients from the list of stream requests StreamServer.OnClientConnected += (s, e) => Core.Instance.StreamClientConnected(e.Client); StreamServer.OnClientDisconnected += (s, e) => Core.Instance.StreamClientDisconnected(e.Client); // Validate stream client identifiers StreamServer.OnClientRequestingConnection += (s, e) => { if (RPCServer.Clients.Any(c => c.Guid == e.Client.Guid)) { e.Request.Allow(); } else { e.Request.Deny(); } }; }
void PollRequests(IList <RequestContinuation> yieldedContinuations) { if (clientScheduler.Empty) { return; } pollRequestsCurrentClients.Clear(); for (int i = 0; i < rpcContinuations.Count; i++) { pollRequestsCurrentClients.Add(rpcContinuations [i].Client); } for (int i = 0; i < yieldedContinuations.Count; i++) { pollRequestsCurrentClients.Add(yieldedContinuations [i].Client); } var item = clientScheduler.Items.First; while (item != null) { var client = item.Value; var stream = client.Stream; try { if (!pollRequestsCurrentClients.Contains(client) && stream.DataAvailable) { Request request = stream.Read(); EventHandlerExtensions.Invoke(OnClientActivity, this, new ClientActivityEventArgs(client)); if (Logger.ShouldLog(Logger.Severity.Debug)) { Logger.WriteLine("Received request from client " + client.Address + " (" + string.Join(", ", request.Calls.Select(call => call.Service + "." + call.Procedure).ToArray()) + ")", Logger.Severity.Debug); } rpcContinuations.Add(new RequestContinuation(client, request)); } } catch (ClientDisconnectedException) { Logger.WriteLine("Client " + client.Address + " disconnected"); client.Stream.Close(); continue; } catch (ServerException e) { Logger.WriteLine("Error receiving request from client " + client.Address + ": " + e.Message, Logger.Severity.Error); client.Stream.Close(); continue; } catch (System.Exception e) { var response = new Response(); response.Error = new Error("Error receiving message" + Environment.NewLine + e.Message, e.StackTrace); if (Logger.ShouldLog(Logger.Severity.Debug)) { Logger.WriteLine(e.Message + Environment.NewLine + e.StackTrace, Logger.Severity.Error); } try { client.Stream.Write(response); Logger.WriteLine("Sent error response to client " + client.Address + " (" + response.Error + ")", Logger.Severity.Debug); } catch (ServerException exn) { Logger.WriteLine("Failed to send error response to client " + client.Address + Environment.NewLine + exn, Logger.Severity.Error); } } item = item.Next; } }
public void Update() { try { if (client == null && pendingClient == null && port.IsOpen && port.BytesToRead > 0) { Logger.WriteLine( "SerialIO.Server[" + Address + "]: client requesting connection", Logger.Severity.Debug); pendingClient = new ByteClient(port); } } catch (IOException) { Stop(); } catch (TimeoutException) { Stop(); } catch (ObjectDisposedException) { Stop(); } if (client == null && pendingClient != null) { // Trigger OnClientRequestingConnection events to verify the connection var args = new ClientRequestingConnectionEventArgs <byte, byte> (pendingClient); EventHandlerExtensions.Invoke(OnClientRequestingConnection, this, args); // Deny the connection if (args.Request.ShouldDeny) { Logger.WriteLine( "SerialIO.Server[" + Address + "]: client connection denied", Logger.Severity.Debug); DisconnectClient(pendingClient, true); pendingClient = null; } // Allow the connection else if (args.Request.ShouldAllow) { client = pendingClient; pendingClient = null; Logger.WriteLine( "SerialIO.Server[" + Address + "]: " + "client connection accepted", Logger.Severity.Debug); EventHandlerExtensions.Invoke(OnClientConnected, this, new ClientConnectedEventArgs <byte, byte> (client)); } // Still pending, will either be denied or allowed on a subsequent called to Update else { Logger.WriteLine( "SerialIO.Server[" + Address + "]: " + "client connection still pending", Logger.Severity.Debug); } } else if (client != null && !client.Connected) { DisconnectClient(client); client = null; } }
public void Should_get_all_handled_events_form_class() { var supportedEvents = EventHandlerExtensions.GetEventTypesWhichHandlerSupports <TestHandler>(); supportedEvents.Should().HaveCount(2); supportedEvents.Should().Contain(typeof(EventA)); supportedEvents.Should().Contain(typeof(EventB)); }
void HandleClientDisconnected(object sender, ClientEventArgs <byte, byte> args) { var client = clients [args.Client]; var stream = client.Stream; closedClientsBytesRead += stream.BytesRead; closedClientsBytesWritten += stream.BytesWritten; clients.Remove(args.Client); EventHandlerExtensions.Invoke(OnClientDisconnected, this, new ClientDisconnectedEventArgs <Request, Response> (client)); }
protected RPCServer(IServer <byte, byte> innerServer) { Server = innerServer; Server.OnStarted += (s, e) => EventHandlerExtensions.Invoke(OnStarted, this); Server.OnStopped += (s, e) => EventHandlerExtensions.Invoke(OnStopped, this); Server.OnClientRequestingConnection += HandleClientRequestingConnection; Server.OnClientConnected += HandleClientConnected; Server.OnClientConnected += HandleClientActivity; Server.OnClientDisconnected += HandleClientDisconnected; }
public void Stop() { if (!Running) { return; } Logger.WriteLine("SerialIO.Server: stop requested", Logger.Severity.Debug); Close(); Logger.WriteLine("SerialIO.Server: stopped successfully", Logger.Severity.Debug); EventHandlerExtensions.Invoke(OnStopped, this); }
public IDisposable Connect() { var connectionId = EventHandlerExtensions.OnConnected(Session, OperatorInfo); var disp = _connectableObservable.Connect(); return(Disposable.Create(() => { disp.Dispose(); Session.OnDisconnected(Event.Disconnect(connectionId)); })); }
void PollRequests(IList <RequestContinuation> yieldedContinuations) { if (clientScheduler.Empty) { return; } pollRequestsCurrentClients.Clear(); for (int i = 0; i < continuations.Count; i++) { pollRequestsCurrentClients.Add(continuations [i].Client); } for (int i = 0; i < yieldedContinuations.Count; i++) { pollRequestsCurrentClients.Add(yieldedContinuations [i].Client); } var item = clientScheduler.Items.First; while (item != null) { var client = item.Value; var stream = client.Stream; try { if (!pollRequestsCurrentClients.Contains(client) && stream.DataAvailable) { Request request = stream.Read(); EventHandlerExtensions.Invoke(OnClientActivity, this, new ClientActivityEventArgs(client)); if (Logger.ShouldLog(Logger.Severity.Debug)) { Logger.WriteLine("Received request from client " + client.Address + " (" + request.Service + "." + request.Procedure + ")", Logger.Severity.Debug); } continuations.Add(new RequestContinuation(client, request)); } } catch (ServerException e) { Logger.WriteLine("Error receiving request from client " + client.Address + ": " + e.Message, Logger.Severity.Error); client.Stream.Close(); continue; } catch (Exception e) { var response = new Response(); response.HasError = true; response.Error = "Error receiving message" + Environment.NewLine + e.Message + Environment.NewLine + e.StackTrace; response.Time = GetUniversalTime(); if (Logger.ShouldLog(Logger.Severity.Debug)) { Logger.WriteLine(e.Message + Environment.NewLine + e.StackTrace, Logger.Severity.Error); } Logger.WriteLine("Sent error response to client " + client.Address + " (" + response.Error + ")", Logger.Severity.Debug); client.Stream.Write(response); } item = item.Next; } }
void Configure(IServer server) { server.OnStarted += (s, e) => { Logger.WriteLine("Server '" + ((Server.Server)s).Name + "' started"); AnyRunning = true; EventHandlerExtensions.Invoke(OnServerStarted, this, new ServerStartedEventArgs((Server.Server)s)); }; server.OnStopped += (s, e) => { Logger.WriteLine("Server '" + ((Server.Server)s).Name + "' stopped"); AnyRunning = Servers.Any(x => x.Running); EventHandlerExtensions.Invoke(OnServerStopped, this, new ServerStoppedEventArgs((Server.Server)s)); }; server.OnClientRequestingConnection += (s, e) => EventHandlerExtensions.Invoke(OnClientRequestingConnection, this, e); }
public void Update() { // Remove disconnected clients for (int i = clients.Count - 1; i >= 0; i--) { var client = clients [i]; if (!client.Connected) { clients.RemoveAt(i); DisconnectClient(client); } } // Process pending clients lock (pendingClientsLock) { if (pendingClients.Count > 0) { var stillPendingClients = new List <TCPClient> (); foreach (var client in pendingClients) { // Trigger OnClientRequestingConnection events to verify the connection var args = new ClientRequestingConnectionEventArgs <byte, byte> (client); EventHandlerExtensions.Invoke(OnClientRequestingConnection, this, args); // Deny the connection if (args.Request.ShouldDeny) { Logger.WriteLine("TCPServer: client connection denied (" + client.Address + ")", Logger.Severity.Debug); DisconnectClient(client, true); } // Allow the connection else if (args.Request.ShouldAllow) { Logger.WriteLine("TCPServer: client connection accepted (" + client.Address + ")", Logger.Severity.Debug); clients.Add(client); EventHandlerExtensions.Invoke(OnClientConnected, this, new ClientConnectedEventArgs <byte, byte> (client)); } // Still pending, will either be denied or allowed on a subsequent called to Update else { Logger.WriteLine("TCPServer: client connection still pending (" + client.Address + ")", Logger.Severity.Debug); stillPendingClients.Add(client); } } pendingClients = stillPendingClients; } } }
public void Close() { if (Visible) { try { Destroy(popup.gameObject); } catch (NullReferenceException) { // FIXME: Nasty hack catching this. Dialog may have already been removed by other UI logic. } Visible = false; dialog = null; popup = null; Closed(); EventHandlerExtensions.Invoke(OnClose, this); } }
public void Start() { if (OnClientRequestingConnection == null) { throw new ServerException("Client request handler not set"); } if (running) { Logger.WriteLine("TCPServer: start requested, but server is already running", Logger.Severity.Warning); return; } Logger.WriteLine("TCPServer: starting", Logger.Severity.Debug); tcpListener = new TcpListener(ListenAddress, ListenPort); try { tcpListener.Start(); } catch (SocketException exn) { string socketError = "socket error '" + exn.SocketErrorCode + "': " + exn.Message; Logger.WriteLine("TCPServer: failed to start server; " + socketError, Logger.Severity.Error); throw new ServerException(socketError); } var endPoint = (IPEndPoint)tcpListener.LocalEndpoint; actualPort = (ushort)endPoint.Port; startedEvent = new AutoResetEvent(false); listenerThread = new Thread(ListenerThread); listenerThread.Start(); startedEvent.WaitOne(500); if (!running) { Logger.WriteLine("TCPServer: failed to start server, timed out waiting for TcpListener to start", Logger.Severity.Error); listenerThread.Abort(); listenerThread.Join(); tcpListener = null; throw new ServerException("Failed to start server, timed out waiting for TcpListener to start"); } EventHandlerExtensions.Invoke(OnStarted, this); Logger.WriteLine("TCPServer: started successfully", Logger.Severity.Debug); if (ListenAddress.ToString() == "0.0.0.0") { Logger.WriteLine("TCPServer: listening on all local network interfaces", Logger.Severity.Debug); } else { Logger.WriteLine("TCPServer: listening on local address " + Address, Logger.Severity.Debug); } Logger.WriteLine("TCPServer: listening on port " + actualPort, Logger.Severity.Debug); }
void DisconnectClient(IClient <byte, byte> client, bool noEvent = false) { var clientAddress = client.Address; try { var stream = client.Stream; closedClientsBytesRead += stream.BytesRead; closedClientsBytesWritten += stream.BytesWritten; } catch (ClientDisconnectedException) { } client.Close(); if (!noEvent) { EventHandlerExtensions.Invoke(OnClientDisconnected, this, new ClientDisconnectedEventArgs <byte, byte> (client)); } Logger.WriteLine("TCPServer: client disconnected (" + clientAddress + ")"); }
public void OnGUI() { if (!hasInit) { var skin = Skin.DefaultSkin; Style = new GUIStyle(skin.window); Init(); closeButtonStyle = new GUIStyle(skin.button); closeButtonStyle.margin = new RectOffset(0, 0, 0, 0); closeButtonStyle.padding = new RectOffset(0, 0, 0, 0); hasInit = true; } if (Visible) { var newUiScale = (int)(GameSettings.UI_SCALE * 100); if (uiScale != newUiScale) { rescale = true; uiScale = newUiScale; Style.fontSize = (int)(14 * GameSettings.UI_SCALE); closeButtonStyle.fixedWidth = 16 * GameSettings.UI_SCALE; closeButtonStyle.fixedHeight = 16 * GameSettings.UI_SCALE; } var newPosition = GUILayout.Window(id, Position, DrawWindow, Title, Style); if (newPosition != Position) { if (!moving) { moving = true; EventHandlerExtensions.Invoke(OnStartMoving, this, new MovedEventArgs(Position)); } movingCounter = 0; } Position = newPosition; } if (moving) { if (movingCounter > 50) { moving = false; EventHandlerExtensions.Invoke(OnFinishMoving, this, new MovedEventArgs(Position)); } movingCounter++; } }
public virtual IDisposable Subscribe(IObserver <T> observer) { // Parent is not a tracked observable. if (_parentInfo == null) { return(_parent.Subscribe(observer)); } var subscriptionId = EventHandlerExtensions.OnSubscribe(_session, _childInfo, _parentInfo); var disp = _parent.Subscribe(observer); return(Disposable.Create(() => { disp.Dispose(); EventHandlerExtensions.OnUnsubscribe(_session, subscriptionId); })); }
public void Open() { if (!hasInit) { Init(); hasInit = true; } if (!Visible) { if (Skin == null) { Skin = HighLogic.UISkin; } Visible = true; Opened(); EventHandlerExtensions.Invoke(OnOpen, this); dialog = new MultiOptionDialog(Message, Title, Skin, Options.ToArray()); popup = PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), dialog, true, HighLogic.UISkin); } }
void DrawStartServer() { var running = core.AnyRunning; var label = (running ? stopAllServersText : startAllServersText) + (core.Servers.Count > 1 ? "s" : string.Empty); GUI.enabled = !editServers.Any(); if (GUILayout.Button(label, buttonStyle)) { Errors.Clear(); Resized = true; foreach (var server in core.Servers) { if (server.Running == running) { EventHandlerExtensions.Invoke(running ? OnStopServerPressed : OnStartServerPressed, this, new ServerEventArgs(server)); } } } GUI.enabled = true; }
void DrawStartStopButton() { if (Server.Running) { if (GUILayout.Button(stopButtonText, buttonStyle)) { EventHandlerExtensions.Invoke(OnStopServerPressed, this); // Force window to resize to height of content // TODO: better way to do this? Position = new Rect(Position.x, Position.y, Position.width, 0f); } } else { if (GUILayout.Button(startButtonText, buttonStyle)) { if (StartServer()) { EventHandlerExtensions.Invoke(OnStartServerPressed, this); } } } }
internal Server(Guid id, Protocol protocol, string name, IServer <Request, Response> rpcServer, IServer <NoMessage, StreamUpdate> streamServer) { Id = id; Protocol = protocol; Name = name; RPCServer = rpcServer; StreamServer = streamServer; // Tie events to underlying server RPCServer.OnStarted += (s, e) => EventHandlerExtensions.Invoke(OnStarted, this); RPCServer.OnStopped += (s, e) => EventHandlerExtensions.Invoke(OnStopped, this); RPCServer.OnClientRequestingConnection += (s, e) => EventHandlerExtensions.Invoke(OnClientRequestingConnection, s, e); RPCServer.OnClientConnected += (s, e) => EventHandlerExtensions.Invoke(OnClientConnected, s, new ClientConnectedEventArgs(e.Client)); RPCServer.OnClientDisconnected += (s, e) => EventHandlerExtensions.Invoke(OnClientDisconnected, s, new ClientDisconnectedEventArgs(e.Client)); // Add/remove clients from the scheduler RPCServer.OnClientConnected += (s, e) => Core.Instance.RPCClientConnected(e.Client); RPCServer.OnClientDisconnected += (s, e) => Core.Instance.RPCClientDisconnected(e.Client); // Add/remove clients from the list of stream requests StreamServer.OnClientConnected += (s, e) => Core.Instance.StreamClientConnected(e.Client); StreamServer.OnClientDisconnected += (s, e) => Core.Instance.StreamClientDisconnected(e.Client); // Validate stream client identifiers StreamServer.OnClientRequestingConnection += (s, e) => { if (RPCServer.Clients.Any(c => c.Guid == e.Client.Guid)) { Logger.WriteLine("Accepting stream server connection (" + e.Client.Address + ")", Logger.Severity.Debug); e.Request.Allow(); } else { Logger.WriteLine("Denying stream server connection, invalid client id (" + e.Client.Address + ")", Logger.Severity.Debug); e.Request.Deny(); } }; }
internal void RPCClientConnected(IClient <Request, Response> client) { rpcClients [client.Guid] = client; clientScheduler.Add(client); EventHandlerExtensions.Invoke(OnClientConnected, this, new ClientConnectedEventArgs(client)); }
internal void StreamClientDisconnected(IClient <NoMessage, StreamMessage> client) { streamClients.Remove(client.Guid); streamRequests.Remove(client); EventHandlerExtensions.Invoke(OnStreamClientDisconnected, this, new ClientDisconnectedEventArgs(client)); }
internal void RPCClientDisconnected(IClient <Request, Response> client) { rpcClients.Remove(client.Guid); clientScheduler.Remove(client); EventHandlerExtensions.Invoke(OnClientDisconnected, this, new ClientDisconnectedEventArgs(client)); }
void HandleClientActivity(object sender, ClientEventArgs <byte, byte> args) { var client = clients [args.Client]; EventHandlerExtensions.Invoke(OnClientActivity, this, new ClientActivityEventArgs <Request, Response> (client)); }