public async void ServerHandlesRequestFire() { // Arrange var serialPort = new FakeSerialPort(); var server = new ModbusRtuServer(unitIdentifier: 1); server.Start(serialPort); var client = new ModbusRtuClient(); client.Connect(serialPort); await Task.Run(() => { var data = Enumerable.Range(0, 20).Select(i => (float)i).ToArray(); var sw = Stopwatch.StartNew(); var iterations = 10000; for (int i = 0; i < iterations; i++) { client.WriteMultipleRegisters(0, 0, data); } var timePerRequest = sw.Elapsed.TotalMilliseconds / iterations; _logger.WriteLine($"Time per request: {timePerRequest * 1000:F0} us. Frequency: {1 / timePerRequest * 1000:F0} requests per second."); client.Close(); }); server.Stop(); // Assert }
static async Task Main(string[] args) { /* Modbus RTU uses a COM port for communication. Therefore, to run * this sample, you need to make sure that there are real or virtual * COM ports available. The easiest way is to install one of the free * COM port bridges available in the internet. That way, the Modbus * server can connect to e.g. COM1 which is virtually linked to COM2, * where the client is connected to. * * When you only want to use the client and communicate to an external * Modbus server, simply remove all server related code parts in this * sample and connect to real COM port using only the client. */ /* define COM ports */ var serverPort = "COM1"; var clientPort = "COM2"; /* prepare dependency injection */ var services = new ServiceCollection(); ConfigureServices(services); /* create types */ var provider = services.BuildServiceProvider(); var loggerFactory = provider.GetRequiredService <ILoggerFactory>(); var serverLogger = loggerFactory.CreateLogger("Server"); var clientLogger = loggerFactory.CreateLogger("Client"); /* create Modbus RTU server and client */ var server = new ModbusRtuServer(unitIdentifier: 1); var client = new ModbusRtuClient(); /* run Modbus RTU server */ var cts = new CancellationTokenSource(); var task_server = Task.Run(async() => { server.Start(serverPort); serverLogger.LogInformation("Server started."); while (!cts.IsCancellationRequested) { // lock is required to synchronize buffer access between this application and the Modbus client lock (server.Lock) { DoServerWork(server); } // update server buffer content once per second await Task.Delay(TimeSpan.FromSeconds(1)); } server.Dispose(); }, cts.Token); /* run Modbus RTU client */ var task_client = Task.Run(() => { client.Connect(clientPort); try { DoClientWork(client, clientLogger); } catch (Exception ex) { clientLogger.LogError(ex.Message); } client.Close(); Console.WriteLine("Tests finished. Press any key to continue."); Console.ReadKey(true); }); // wait for client task to finish await task_client; // stop server cts.Cancel(); await task_server; server.Stop(); serverLogger.LogInformation("Server stopped."); }
static async Task Main(string[] args) { /* Modbus RTU uses a COM port for communication. Therefore, to run * this sample, you need to make sure that there are real or virtual * COM ports available. The easiest way is to install one of the free * COM port bridges available in the internet. That way, the Modbus * server can connect to e.g. COM1 which is virtually linked to COM2, * where the client is connected to. * * When you only want to use the client and communicate to an external * Modbus server, simply remove all server related code parts in this * sample and connect to real COM port using only the client. */ /* define COM ports */ var serverPort = "COM1"; var clientPort = "COM2"; /* create logger */ var loggerFactory = LoggerFactory.Create(loggingBuilder => { loggingBuilder.SetMinimumLevel(LogLevel.Debug); loggingBuilder.AddConsole(); }); var serverLogger = loggerFactory.CreateLogger("Server"); var clientLogger = loggerFactory.CreateLogger("Client"); /* create Modbus RTU server */ using var server = new ModbusRtuServer(unitIdentifier: 1) { // see 'RegistersChanged' event below EnableRaisingEvents = true }; /* subscribe to the 'RegistersChanged' event (in case you need it) */ server.RegistersChanged += (sender, registerAddresses) => { // the variable 'registerAddresses' contains a list of modified register addresses }; /* create Modbus RTU client */ var client = new ModbusRtuClient(); /* run Modbus RTU server */ var cts = new CancellationTokenSource(); var task_server = Task.Run(async() => { server.Start(serverPort); serverLogger.LogInformation("Server started."); while (!cts.IsCancellationRequested) { // lock is required to synchronize buffer access between this application and the Modbus client lock (server.Lock) { DoServerWork(server); } // update server register content once per second await Task.Delay(TimeSpan.FromSeconds(1)); } }, cts.Token); /* run Modbus RTU client */ var task_client = Task.Run(() => { client.Connect(clientPort); try { DoClientWork(client, clientLogger); } catch (Exception ex) { clientLogger.LogError(ex.Message); } client.Close(); Console.WriteLine("Tests finished. Press any key to continue."); Console.ReadKey(true); }); // wait for client task to finish await task_client; // stop server cts.Cancel(); await task_server; server.Stop(); serverLogger.LogInformation("Server stopped."); }