APM runs a local WebSocket server that enables real-time communication between web applications (Appsiel Cloud POS) and the local print manager. The server listens on port 7000 and handles print job requests, scale data streaming, and template updates.
public Task StartServerAsync(int port){ lock (_lockObject) { if (_server != null) { _logger.LogWarning("El servidor WebSocket ya está en ejecución."); return Task.CompletedTask; } // Create Watson WebSocket server instance // Listen on all interfaces ("+") to allow external connections // Parameters: IP, Port, SSL enabled _server = new WatsonWsServer("+", port, false); // Subscribe to server events _server.ClientConnected += OnWatsonClientConnected; _server.ClientDisconnected += OnWatsonClientDisconnected; _server.MessageReceived += OnWatsonMessageReceived; // Start the server _server.Start(); _logger.LogInfo($"Servidor WebSocket iniciado en puerto {port}"); } return Task.CompletedTask;}
The server binds to all network interfaces ("+") to enable access from web browsers on the same machine and local network. Ensure firewall rules allow inbound connections on port 7000.
public async Task SendPrintJobResultToAllClientsAsync(PrintJobResult result){ if (_server == null) { _logger.LogWarning("No se puede enviar PrintJobResult, el servidor no está en ejecución."); return; } try { var json = JsonSerializer.Serialize(result); var clients = _server.ListClients(); if (clients == null || !clients.Any()) { _logger.LogWarning("No hay clientes conectados para enviar PrintJobResult."); return; } foreach (var client in clients) { try { await _server.SendAsync(client.Guid, json); _logger.LogInfo($"PrintJobResult enviado al cliente {client.Guid}"); } catch (Exception ex) { _logger.LogError($"Error al enviar PrintJobResult al cliente {client.Guid}: {ex.Message}"); } } } catch (Exception ex) { _logger.LogError($"Error al serializar o enviar PrintJobResult: {ex.Message}"); }}
public async Task SendPrintJobResultToClientAsync(string clientId, PrintJobResult result){ if (_server == null) { _logger.LogWarning("No se puede enviar PrintJobResult, el servidor no está en ejecución."); return; } try { // Convert string clientId to Guid if (!Guid.TryParse(clientId, out var clientGuid)) { _logger.LogError($"Client ID inválido: {clientId}"); return; } var json = JsonSerializer.Serialize(result); await _server.SendAsync(clientGuid, json); _logger.LogInfo($"PrintJobResult enviado al cliente específico {clientId}"); } catch (Exception ex) { _logger.LogError($"Error al enviar PrintJobResult al cliente {clientId}: {ex.Message}"); }}
public async Task SendTemplateUpdateResultAsync(string clientId, TemplateUpdateResult result){ if (_server == null) { _logger.LogWarning("No se puede enviar TemplateUpdateResult, el servidor no está en ejecución."); return; } try { if (!Guid.TryParse(clientId, out var clientGuid)) { _logger.LogError($"Client ID inválido para TemplateUpdateResult: {clientId}"); return; } var json = JsonSerializer.Serialize(result); await _server.SendAsync(clientGuid, json); _logger.LogInfo($"TemplateUpdateResult enviado al cliente {clientId}"); } catch (Exception ex) { _logger.LogError($"Error al enviar TemplateUpdateResult al cliente {clientId}: {ex.Message}"); }}
The WebSocket server runs without SSL/TLS (ws:// not wss://) for local development simplicity. It’s designed for same-machine or trusted local network access only.