public ServerConnection(Socket socket, ServiceDispatcher dispatcher, ServiceHostConfig config, ServiceHostCounters counters, ISerializer serializer, X509Certificate?certificate) { _dispatcher = dispatcher; _socket = socket; _config = config; _requestLogger = new RequestLogger(socket.GetRemoteAddressName(), dispatcher.MessageMap); Stream readerStream, writerStream; if (config.TlsSettings == null || certificate == null) { readerStream = new NetworkStream(socket, FileAccess.Read, false); writerStream = new NetworkStream(socket, FileAccess.Write, false); } else { var networkStream = new NetworkStream(socket, FileAccess.ReadWrite, false); var tlsStream = new SslStream(networkStream, true); readerStream = writerStream = tlsStream; _tls = new TlsData(certificate, tlsStream); } _messageReader = new DelimitedMessageReader(socket.GetRemoteAddressName(), readerStream, serializer); _messageWriter = new DelimitedMessageWriter(socket.GetRemoteAddressName(), writerStream, serializer); _responsePropagatorTask = PropagateResponses(); _counters = counters; }
private static void LogDispatcher(ServiceDispatcher dispatcher) { _logger.Info("The following message handlers found:"); foreach ((int requestId, int responseId) in dispatcher.GetRequestResponseMap()) { Type requestType = dispatcher.MessageMap.GetMessageTypeById(requestId); Type?responseType = responseId > 0 ? dispatcher.MessageMap.GetMessageTypeById(responseId) : null; if (responseType != null) { _logger.Info(" {0} -> {1}", requestType.Name, responseType.Name); } else { _logger.Info(" {0}", requestType.Name); } } }
public async Task Start(ServiceHostConfig config) { if (_listeningSocket != null) { throw new InvalidOperationException("Service host is already started."); } try { ConfigureLogger(config); LoadMessageAssemblies(config.MessageAssemblies); LoadServiceAssemblies(config.ServiceAssemblies); var incomingSerializer = (ISerializer)Activator.CreateInstance(Type.GetType(config.Serializer)); var outgoingSerializer = (ISerializer)Activator.CreateInstance(Type.GetType(config.ClusterConnectionSettings.Serializer)); InitSignalHandlers(); X509Certificate?certificate = await LoadCertificate(config); var session = new Session(); var counters = new ServiceHostCounters(); using ClusterConnection clusterConnection = CreateClusterConnection(config, outgoingSerializer); using IContainer container = BuildContainer(config, clusterConnection, session); var dispatcher = new ServiceDispatcher(container, _serviceTypes, clusterConnection); _listeningSocket = new Socket(SocketType.Stream, ProtocolType.IP); _listeningSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _listeningSocket.Bind(new IPEndPoint(IPAddress.Any, config.Port)); _listeningSocket.Listen(128); if (config.Gateway) { _logger.Info("Server started as gateway. Listening port {0}...", config.Port); } else { _logger.Info("Server started. Listening port {0}...", config.Port); } Task clusterConnectionTask = ConnectCluster(config, clusterConnection); Task callbacksInvocationTask = UpdateClusterConnection(config, clusterConnection); // If it is a gateway, the host waits for the cluster connection to obtain // message maps, initializes routes and only then accepts connections. // // The first connection attempt tries to connect only once, so it is assumed // that the cluster itself is completely up before all its gateways. if (config.Gateway) { await clusterConnectionTask; dispatcher.InitGatewayRouts(); } LogDispatcher(dispatcher); int nextConnectionId = 1; while (true) { Socket connectionSocket; try { connectionSocket = await _listeningSocket.AcceptAsync(); } catch (SocketException) { _logger.Info("The listening socket is closed. The host is going to shutdown."); break; } _logger.Info("Client connected {0}.", connectionSocket.GetRemoteAddressName()); ServeConnection( new ServerConnection( connectionSocket, dispatcher, config, counters, incomingSerializer, certificate ), config, session, nextConnectionId++ ); } _updateClusterConnection = false; await clusterConnectionTask; await callbacksInvocationTask; } catch (Exception ex) { _logger.Fatal(ex, "Service host faulted."); } finally { _listeningSocket?.Dispose(); _listeningSocket = null; _logger.Info("Service host stopped."); LogManager.Flush(); _serviceHostStopped.Set(); } }