DEV Community

ben
ben

Posted on

Practical Combat of MAUI Embedded Web Architecture (7) PicoServer + WebSocket: Building Real-Time Device Communication and Control Systems

PicoServer
Source Code URL:
https://github.com/densen2014/MauiPicoAdmin

I. Why WebSocket Is Needed

In the previous articles, we have implemented a complete architecture:

Web Admin UI
      ↓
PicoServer REST API
      ↓
MAUI Service
      ↓
SQLite / Device
Enter fullscreen mode Exit fullscreen mode

Web APIs are suitable for:

  • CRUD operations
  • Request-response workflows

However, for real-time systems, REST APIs have obvious limitations.

For example:

Scenario Issues with REST API
Device status changes Requires continuous polling
Real-time logging High latency
Device control Slow interaction

Take browsers as an example: they send a request to /api/device/status every second. This is called Polling.

Problems with polling:

  • High server load
  • High latency
  • Poor user experience

The solution is WebSocket.

II. What Is WebSocket

WebSocket is a persistent connection communication protocol.

Communication mode:

Browser
   ⇅
WebSocket
   ⇅
Server
Enter fullscreen mode Exit fullscreen mode

Key features:

Feature Description
Bidirectional communication Both client and server can send data
Persistent connection No need to repeatedly establish connections
Real-time performance Millisecond-level latency

Therefore, it is ideal for:

  • Device control
  • Real-time logging
  • Message pushing
  • IoT systems

III. System Architecture Upgrade

After integrating WebSocket, the architecture becomes:

           Web Admin
             │
      ┌──────┴───────┐
      │              │
 REST API        WebSocket
      │              │
      ▼              ▼
         PicoServer
              │
              ▼
            Service
              │
              ▼
         Device / DB
Enter fullscreen mode Exit fullscreen mode

REST API: Handles CRUD operations
WebSocket: Manages real-time communication and device control

IV. Code Implementation of WebSocket Server

Add a WebSocketManager to PicoServer.

Create the file: Services/WebSocketManager.cs

Sample implementation:

using PicoServer;

public class WebSocketManager
{
    private WebAPIServer? api;

    public void RegisterWebSocket(WebAPIServer api)
    {
        this.api = api;
        api.enableWebSocket = true; 
        api.WsOnConnectionChanged = WsConnectChanged;
        api.WsOnMessage = OnMessageReceived;
    }

    public async Task OnMessageReceived(string clientId, string message, Func<string, Task> reply)
    {
        await reply("Received!");
        var clients = api!.WsGetOnlineClients();
        foreach (var client in clients)
        {
            await api.WsSendToClientAsync(client, $"{clientId} says: {message}");
        }
    } 

    public async Task WsConnectChanged(string clientId, bool connected)
    {
        await api!.WsBroadcastAsync($"{clientId} {connected}");
    }
}
Enter fullscreen mode Exit fullscreen mode

This component implements:

  • Connection management
  • Message reception
  • Message broadcasting

V. Register WebSocket Routes

Register WebSocket in the ServerHost:

ws.RegisterWebSocket(api);
Enter fullscreen mode Exit fullscreen mode

Now browsers can connect via:

ws://localhost:8090/ws
Enter fullscreen mode Exit fullscreen mode

VI. Frontend WebSocket Connection

In the Web Admin interface:

const ws = new WebSocket("ws://127.0.0.1:8090/ws");

ws.onopen = () => {
  console.log("WebSocket Connected");
};

ws.onmessage = (event) => {
  console.log("Message:", event.data);
};

ws.onclose = () => {
  console.log("Disconnected");
};

function send() {
  ws.send("hello device");
}
Enter fullscreen mode Exit fullscreen mode

Send messages with:

ws.send("hello device");
Enter fullscreen mode Exit fullscreen mode

VII. Device Control Protocol Design

In practical systems, you need to define a communication protocol. JSON is recommended.

Examples:

Device control:

{
  "type": "device_control",
  "device": "printer",
  "cmd": "start"
}
Enter fullscreen mode Exit fullscreen mode

Device status:

{
  "type": "device_status",
  "device": "printer",
  "status": "running"
}
Enter fullscreen mode Exit fullscreen mode

Log message:

{
  "type": "log",
  "message": "device started"
}
Enter fullscreen mode Exit fullscreen mode

VIII. Server-Side Device Command Handling

Parse WebSocket messages:

var cmd = JsonSerializer.Deserialize<WsCommand>(msg);

switch(cmd.Type)
{
    case "device_control":
        DeviceService.Execute(cmd.Device, cmd.Cmd);
        break;
}
Enter fullscreen mode Exit fullscreen mode

Example:

DeviceService.Execute("printer","start");
Enter fullscreen mode Exit fullscreen mode

IX. Real-Time Device Status Pushing

When device status changes:

await ws.Broadcast(JsonSerializer.Serialize(new
{
    type = "device_status",
    device = "printer",
    status = "running"
}));
Enter fullscreen mode Exit fullscreen mode

The frontend receives the message immediately:

ws.onmessage = e => {
    let msg = JSON.parse(e.data);
    if(msg.type === "device_status")
    {
        updateUI(msg);
    }
}
Enter fullscreen mode Exit fullscreen mode

This enables real-time updates in the flow: Device → Server → Web Admin

Click to expand complete sample code
Click to expand complete backend code

X. Real-Time Logging System

For device logs:

await ws.Broadcast(JsonSerializer.Serialize(new
{
    type="log",
    message="print job started"
}));
Enter fullscreen mode Exit fullscreen mode

Frontend implementation:

if(msg.type==="log"){
   logPanel.append(msg.message)
}
Enter fullscreen mode Exit fullscreen mode

Effect: A real-time log window

XI. Complete Real-Time Architecture

The final system architecture is:

                 Web Admin UI
                /            \
          REST API        WebSocket
              │               │
              ▼               ▼
             PicoServer Core
                    │
                    ▼
                 Services
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
       SQLite              Device
Enter fullscreen mode Exit fullscreen mode

The system's capabilities are now upgraded to include:

  • Backend management
  • Real-time communication
  • Device control
  • Data storage

XII. Summary of This Article

In this article, we added the following core capabilities to the system:

  • WebSocket real-time communication
  • Device control protocol
  • Real-time log pushing
  • Status synchronization

The system now integrates:

  • Web Admin
  • REST API
  • WebSocket
  • Device control

It can be applied to scenarios such as:

  • IoT systems
  • Device management platforms
  • Local control software
  • Industrial tool systems

Next Article Preview

The next article will take a crucial step in architecture upgrading:

Practical Combat of MAUI Embedded Web Architecture (8)
Plug-In API Architecture: Automatic Controller Discovery and Modular Expansion

We will implement:

  • Plug-in loading
  • Module expansion
  • Dynamic APIs
  • Module management

Ultimately, we will upgrade the system into a truly scalable local web platform.

Top comments (0)