ΣΗΜΕΙΩΣΗ: Το άρθρο του είναι κατά κύριο λόγο AI που παράγεται ως μέρος του πακέτου nuget μου ως έγγραφα κυκλοφορίας. Είναι αρκετά ενδιαφέρον γι 'αυτό το βάζω εδώ, αλλά αν αυτό είναι ένα πρόβλημα για σας παρακαλώ αγνοήστε το.
Ως μέρος της δικής μου Nuget πακέτο LLMApi / ως επί το πλείστον διαυγή.mockllmapi Έπρεπε να έχω μια σελίδα για να ενεργοποιήσω τη χρήση των χαρακτηριστικών SignalR που έχει (μπορεί να προσομοιώσει τις feeds SignalR χρησιμοποιώντας LLMs για την παροχή δεδομένων).
Μπορείτε να βρείτε το GitHub εδώ για το έργο, όλος ο δημόσιος τομέας κ.λπ...
Έγινε ένα αρκετά ωραίο εργαλείο!

Αν έχετε ποτέ χρειαστεί να χτίσει ένα ταμπλό ή σε πραγματικό χρόνο UI πριν από την πραγματική πηγή δεδομένων υπάρχει, ξέρετε την πρόκληση. setInterval() βρόχοι που περιστρέφονται μέσα από την ίδια χούφτα των αντικειμένων.
Περιγράφετε τι δεδομένα χρειάζεστε σε απλά αγγλικά, και ένα τοπικό LLM παράγει ρεαλιστικό, ποικίλο JSON που ρέει στο πρόγραμμα περιήγησης σας σε πραγματικό χρόνο. Δεν εξαρτήματα για τη διατήρηση, δεν αρχεία σπόρων για την ενημέρωση, απλά περιγράψτε τι θέλετε και παρακολουθήστε τη ροή.
Επιτρέψτε μου να σας δείξω πώς λειτουργεί και πώς να πάρει το μεγαλύτερο μέρος από αυτό.
Η σελίδα επίδειξης Signer (Index.cshtml) είναι ένας πίνακας ελέγχου για τη διαχείριση των ροών δεδομένων σε πραγματικό χρόνο. Εδώ είναι η βασική ροή:
Είναι ιδιαίτερα χρήσιμο όταν πρωτοτυπείτε, χτίζετε demo, ή εργάζεστε σε frontend χαρακτηριστικά, ενώ περιμένετε το backend APIs να είναι έτοιμο. Τα δεδομένα φαίνονται ρεαλιστικά επειδή το LLM κατανοεί το πλαίσιο και δημιουργεί τις κατάλληλες τιμές.
graph TB
Browser[Your Browser]
UI[Demo UI]
API[Management API]
Hub[SignalR Hub]
Manager[Context Manager]
BG[Background Service]
LLM[LLM Ollama/OpenAI]
Cache[Response Cache]
Browser -->|Create Context| API
API -->|Store Config| Manager
Browser -->|Connect Subscribe| Hub
Hub -->|Register Client| Manager
BG -->|Generate Data| LLM
LLM -->|Return JSON| BG
BG -->|Cache Responses| Cache
BG -->|Push to Clients| Hub
Hub -->|Real-time Updates| Browser
SignalR διατηρεί μια επίμονη σύνδεση WebSocket μεταξύ του προγράμματος περιήγησής σας και του διακομιστή. Αντί να δημοσκοπήσετε ένα τελικό σημείο κάθε λίγα δευτερόλεπτα με τα αιτήματα HTTP, ο διακομιστής πιέζει τα δεδομένα όταν είναι έτοιμα.
Είναι η ίδια τεχνολογία που χρησιμοποιείται σε εφαρμογές συνομιλίας, live ταμπλό, και συνεργατικά εργαλεία όπου η άμεση ενημέρωση έχει σημασία.
Ας ξεκινήσουμε με το γρηγορότερο μονοπάτι για να το δούμε να δουλεύει.
Βήμα 1: Ξεκινήστε την εφαρμογή
dotnet run --project LLMApi/LLMApi.csproj
Πλοηγηθείτε στο http://localhost:5116 (ελέγξτε την έξοδο της κονσόλας για την πραγματική θύρα).
Βήμα 2: Χρησιμοποιήστε ένα παράδειγμα γρήγορης εκκίνησης
Θα δείτε πέντε προ-ρυθμισμένα παραδείγματα με πράσινα πλήκτρα "Launch." Κάντε κλικ στο "Stock Market" και τελειώσατε. Η σελίδα αυτόματα:
Βήμα 3: Παρακολουθήστε το ρεύμα δεδομένων
Κάθε 5 δευτερόλεπτα, νέα δεδομένα εμφανίζονται με έμφαση στη σύνταξη. Κάθε ενημέρωση δείχνει διάφορα αποθέματα με ρεαλιστικές τιμές και όγκο συναλλαγών. Η LLM παράγει φρέσκα δεδομένα κάθε φορά, έτσι ώστε να βλέπετε την ποικιλία διατηρώντας ταυτόχρονα τη δομή.
Αυτό είναι! Τώρα διαδίδετε ψεύτικα δεδομένα του χρηματιστηρίου. Μη διστάσετε να εξερευνήσετε τα άλλα παραδείγματα γρήγορης εκκίνησης για να δείτε διαφορετικά μοτίβα δεδομένων.
Τα κουμπιά γρήγορης εκκίνησης είναι εύχρηστα, αλλά η πραγματική δύναμη προέρχεται από την περιγραφή ακριβώς τι χρειάζεστε. Ας δημιουργήσουμε ένα προσαρμοσμένο παράδειγμα.
Παράδειγμα: Τηλεμετρία καφετιέρας
Πες ότι φτιάχνεις ένα ταμπλό IoT και χρειάζεσαι προσομοιωμένα δεδομένα καφετιέρας.
Context Name: coffee-machines
Description: Coffee machine telemetry with machine ID, beans remaining percentage,
water temperature in Celsius, cups brewed today, and last maintenance timestamp
Κάντε κλικ στο "Δημιουργία & Εγγραφή" και είστε μακριά.
sequenceDiagram
participant Browser
participant API
participant Manager
participant BG as Background Service
participant LLM
participant Hub
Browser->>API: POST /api/mock/contexts<br/>{name, description}
API->>Manager: Store context config
Manager-->>API: Context created ✓
API-->>Browser: 200 OK
Browser->>Hub: invoke('SubscribeToContext', 'coffee-machines')
Hub->>Manager: Register subscription
Manager-->>Hub: Subscription confirmed
Hub-->>Browser: on('Subscribed')
Note over BG,LLM: Every 5 seconds...
BG->>LLM: Generate data for 'coffee-machines'<br/>Prompt includes description
LLM-->>BG: JSON response
BG->>Hub: Broadcast to 'coffee-machines' group
Hub-->>Browser: on('DataUpdate', {data})
Browser->>Browser: Display with syntax highlighting
Το σύστημα:
Θα δείτε την έξοδο έτσι:
{
"machineId": "CM-2847",
"beansRemaining": 67,
"waterTemp": 94.5,
"cupsBrewed": 142,
"lastMaintenance": "2025-01-03T08:23:00Z"
}
Κάθε ενημέρωση έχει διαφορετικές τιμές αλλά διατηρεί τη δομή. Η LLM κατανοεί την "τηλεμετρία μηχανών καφέ" και παράγει αριθμούς που έχουν νόημα σε αυτό το πλαίσιο.
Α πλαίσιο είναι μια ρύθμιση που ονομάζεται ροή δεδομένων. Σκεφτείτε το ως κανάλι ή θέμα.
Όταν δημιουργείς ένα, προσδιορίζεις:
weather, stock-market, sensors)Το backend στη συνέχεια:
Πολλαπλά προγράμματα περιήγησης μπορούν να εγγραφούν στο ίδιο πλαίσιο και όλοι λαμβάνουν τα ίδια δεδομένα ταυτόχρονα. Αυτό είναι μεγάλο για τη δοκιμή ταμπλό που πρέπει να δείξει συγχρονισμένες ενημερώσεις σε διαφορετικές οθόνες ή εξαρτήματα.
stateDiagram-v2
[*] --> Created: Create Context<br/>(POST /contexts)
Created --> Active: Start<br/>(auto or manual)
Active --> Stopped: Stop<br/>(POST /stop)
Stopped --> Active: Start<br/>(POST /start)
Created --> Subscribed: Client Subscribes
Active --> Subscribed: Client Subscribes
Stopped --> Subscribed: Client Subscribes<br/>(no data sent)
Subscribed --> Receiving: Data Push<br/>(if Active)
Receiving --> Subscribed: Client Connected
Subscribed --> Created: Unsubscribe
Subscribed --> Active: Unsubscribe
Subscribed --> Stopped: Unsubscribe
Created --> [*]: Delete
Active --> [*]: Delete
Stopped --> [*]: Delete
Subscribed --> [*]: Delete
note right of Active
Generates data
Pushes to clients
Shows "Active" badge
end note
note right of Stopped
No data generation
Clients stay connected
Shows "Stopped" badge
end note
Η διεπαφή έχει τρία πάνελ για να κρατήσει τα πράγματα οργανωμένα:
Εδώ είναι που ορίζεις νέες ροές δεδομένων.
Δεν χρειάζεται να γράψετε JSON schemas ή να εξηγήσετε τύπους δεδομένων. Η LLM infers δομή από φυσικές γλωσσικές περιγραφές εκπληκτικά καλά.
Εμφανίζει όλα τα τρέχοντα συμφραζόμενα σας με:
Σύνδεση/αποσύνδεση Ελέγχει τη συνδρομή του προγράμματος περιήγησης σας. Κάντε κλικ στο Connect για να αρχίσετε να λαμβάνετε δεδομένα, Αποσυνδέστε για να σταματήσετε χωρίς να διαγράψετε το πλαίσιο.
Έναρξη/Σταμάτημα ελέγχει τη δημιουργία δεδομένων backend. Αυτό είναι χρήσιμο όταν θέλετε να διακόψετε ένα ρεύμα χωρίς να καταστρέψετε τη διαμόρφωση του πλαισίου.
Διαγραφή Απομακρύνει εντελώς το πλαίσιο. Χρησιμοποιήστε αυτό για να καθαρίσετε όταν τελειώσετε με ένα συγκεκριμένο ρεύμα δεδομένων.
Εδώ βλέπετε ενημερώσεις σε πραγματικό χρόνο:
Τα δεδομένα εμφανίζονται νεότερα-πρώτα στην κορυφή, έτσι ώστε να βλέπετε πάντα τις τελευταίες ενημερώσεις χωρίς κύλιση.
Η σελίδα χρησιμοποιεί HTMX για υποβολή εντύπων και SignalR για σύνδεση σε πραγματικό χρόνο. Αν χτίζετε το δικό σας πελάτη, εδώ είναι το μοτίβο SignalR που θα χρειαστείτε:
sequenceDiagram
participant Page as Your Page
participant SR as SignalR Client
participant Hub as /hub/mock
participant BG as Background Service
Page->>SR: new HubConnectionBuilder()<br/>.withUrl('/hub/mock')
Page->>SR: connection.start()
SR->>Hub: WebSocket connection
Hub-->>SR: Connected ✓
SR-->>Page: Trigger 'connected' event
Page->>SR: invoke('SubscribeToContext', 'weather')
SR->>Hub: SubscribeToContext('weather')
Hub->>Hub: Add to 'weather' group
Hub-->>SR: on('Subscribed', {context: 'weather'})
SR-->>Page: Display "Subscribed"
loop Every 5 seconds
BG->>Hub: Broadcast to 'weather' group
Hub->>SR: on('DataUpdate', {data, timestamp})
SR->>Page: Update UI with new data
end
Page->>SR: invoke('UnsubscribeFromContext', 'weather')
SR->>Hub: UnsubscribeFromContext('weather')
Hub->>Hub: Remove from 'weather' group
Ρύθμιση της σύνδεσης:
const connection = new signalR.HubConnectionBuilder()
.withUrl('/hub/mock')
.withAutomaticReconnect()
.build();
connection.on('DataUpdate', (message) => {
// message.context: which context sent this
// message.data: the actual JSON payload
// message.timestamp: Unix timestamp in milliseconds
});
await connection.start();
Υπογραφή για τη λήψη δεδομένων:
await connection.invoke('SubscribeToContext', 'my-context-name');
Μη εγγραφή κατά την ολοκλήρωση:
await connection.invoke('UnsubscribeFromContext', 'my-context-name');
Η σελίδα demo χειρίζεται όλα αυτά αυτόματα, αλλά αυτά τα τρία πρότυπα είναι όλα όσα χρειάζεστε για μια προσαρμοσμένη εφαρμογή.
Εδώ είναι μερικά σενάρια όπου αυτό το εργαλείο πραγματικά λάμπει:
1. Κτίριο UIs πριν APIs Exist
Είστε εργάζονται σε ένα ταμπλό και η ομάδα backend εξακολουθεί να σχεδιάζει το σχήμα API. Αντί να μπλοκάρει την εργασία τους, περιγράψτε τη δομή δεδομένων που περιμένετε και να χτίσει UI σας ενάντια στο ρεύμα mock. Όταν το πραγματικό API είναι έτοιμο, απλά θα ανταλλάξετε το τελικό σημείο.
2. Διαδηλώσεις πελατών
Υποβιβάζετε ένα ζωντανό ταμπλό παρακολούθησης σε έναν πελάτη, αλλά ο πραγματικός αγωγός δεδομένων δεν είναι έτοιμος ακόμα. Δημιουργήστε πλαίσια που ταιριάζουν με την προγραμματισμένη δομή δεδομένων σας και εμφανίστε ρεαλιστικά, αλλάζοντας δεδομένα κατά τη διάρκεια της παρουσίασης.
3. Ανάπτυξη και δοκιμή του Frontend
Χρειάζεστε ρεαλιστικά, ποικίλα δεδομένα για να ελέγξετε πώς τα διαγράμματα, πίνακες, και τα συστατικά σας χειρίζονται ενημερώσεις. Δημιουργήστε τα συμφραζόμενα με τις δομές που χρειάζεστε και αναπτύξτε UI σας με εμπιστοσύνη ότι χειρίζεται τα πρότυπα δεδομένων του πραγματικού κόσμου.
4. Δοκιμασία φορτίου γνωρίσματα πραγματικού χρόνου
Θέλετε να δείτε πώς λειτουργεί το UI σας κάτω από γρήγορες ενημερώσεις. Δημιουργήστε ένα πλαίσιο υψηλής συχνότητας και παρακολουθήστε πώς τα στοιχεία σας χειρίζονται τη ροή των δεδομένων.
5. Διδάσκοντας WebSockets και Real-Time Concepts
Διδάσκετε έννοιες SignalR ή WebSocket και θέλετε οι μαθητές να δουν ενημερώσεις σε πραγματικό χρόνο χωρίς να χτίσουν ένα πλήρες backend. Το demo παρέχει ένα παράδειγμα εργασίας με το οποίο μπορούν να πειραματιστούν και να μάθουν.
Τα πέντε προ-ρυθμισμένα παραδείγματα δείχνουν διαφορετικά κοινά πρότυπα δεδομένων:
Αισθητήρες IoTName: Αριθμητικές ενδείξεις αισθητήρων με μεταδεδομένα συσκευής Χρηματιστηριακή αγορά: Οικονομικά στοιχεία με τιμές, όγκους και εκατοστιαίες μεταβολές Διαταγές ηλεκτρονικού εμπορίου: Προτεινόμενα αντικείμενα με συστοιχίες στοιχείων παραγγελίας Μετρικός εξυπηρετητήςName: Παρακολούθηση συστήματος με πολλαπλές μετρήσεις απόδοσης Παιχνίδια Leaderboard: Κατατάξεις παίκτη με στατιστικά και καταστάσεις
Κάντε κλικ στην έναρξη, παρακολουθήστε τα δεδομένα, και να τα χρησιμοποιήσετε ως πρότυπα για τα δικά σας συμφραζόμενα.
Εάν φτιάχνετε ένα προσαρμοσμένο πελάτη ή το ενσωματώνετε σε άλλη εφαρμογή, ορίστε τα τελικά σημεία HTTP:
Δημιουργία ενός πλαισίου:
curl -X POST http://localhost:5116/api/mock/contexts \
-H "Content-Type: application/json" \
-d '{"name": "sensors", "description": "Temperature sensors with device ID and readings"}'
Κατάλογος όλων των συμφρασμάτων:
curl http://localhost:5116/api/mock/contexts
Πάρτε ένα συγκεκριμένο πλαίσιο:
curl http://localhost:5116/api/mock/contexts/sensors
Εκκίνηση ή διακοπή της παραγωγής δεδομένων:
curl -X POST http://localhost:5116/api/mock/contexts/sensors/start
curl -X POST http://localhost:5116/api/mock/contexts/sensors/stop
Διαγραφή πλαισίου:
curl -X DELETE http://localhost:5116/api/mock/contexts/sensors
Μετά τη δημιουργία ενός πλαισίου, συνδεθείτε με τον κόμβο SignalR στο /hub/mock και να εγγραφείτε για να αρχίσετε να λαμβάνετε ενημερώσεις.
Όταν δημιουργείτε ένα πλαίσιο, το σύστημα:
Η θερμοκρασία ορίζεται σε 1.2 (σχετικά υψηλή) για να εξασφαλιστεί η ποικιλία. Όταν ζητάτε "στοιχεία χρήστη," παίρνετε διαφορετικά ονόματα και τιμές κάθε φορά, όχι τα ίδια λίγα ανακυκλωμένα ατελείωτα.
Η παραγωγή δεδομένων συμβαίνει στο παρασκήνιο, όχι κατά παραγγελία ανά ώθηση. Αυτό κρατά τις ενημερώσεις συνεπείς και μειώνει το φορτίο LLM.
Ακούστε πώς λειτουργεί:
Αποτέλεσμα: Το πρώτο σας μήνυμα φτάνει αμέσως, τα επόμενα μηνύματα έρχονται σταθερά κάθε 5 δευτερόλεπτα, και η LLM δεν σφυροκοπήται συνεχώς.
graph LR
subgraph Startup
A[App Starts] --> B[Pre-fill Cache]
B --> C[Measure Gen Time<br/>500ms]
C --> D[Calculate Batch<br/>5000ms / 500ms = 10]
end
subgraph Runtime Loop
E[Timer Tick<br/>Every 5s] --> F{Cache > 50%?}
F -->|Yes| G[Pop from Cache]
F -->|No| H[Generate Batch<br/>in Background]
G --> I[Push to Clients]
H --> J[Refill Cache]
J --> G
I --> E
end
D --> E
style B stroke:#10b981,stroke-width:3px
style G stroke:#0ea5e9,stroke-width:3px
style H stroke:#ef4444,stroke-width:3px
style I stroke:#f59e0b,stroke-width:3px
Η σύνδεση δείχνει "αποσύνδεση" και δεν επανασυνδέεται
http://localhost:11434ollama list για να επαληθεύσετε ότι έχετε εγκατεστημένα μοντέλαΠλαίσιο που δημιουργήθηκε αλλά δεν εμφανίζονται δεδομένα
Η δομή των δεδομένων δεν ταιριάζει με αυτό που περιμένατε.
Η κονσόλα προγράμματος περιήγησης δείχνει απόπειρες επανασύνδεσης Signer
Μπορείτε να προσαρμόσετε τη συμπεριφορά σε appsettings.json:
{
"MockLlmApi": {
"SignalRPushIntervalMs": 5000, // How often to push data (milliseconds)
"ModelName": "llama3", // Which LLM model to use
"Temperature": 1.2, // Creativity level (0.0-2.0, higher = more varied)
"BaseUrl": "http://localhost:11434", // LLM service URL
"HubContexts": [ // Optional: pre-configured contexts
{
"Name": "weather",
"Description": "Weather data with temperature, humidity, wind speed",
"IsActive": true
}
]
}
}
SignalRPushIntervalMs: Ρυθμίστε χαμηλότερα για γρηγορότερες ενημερώσεις, υψηλότερη για τη μείωση του φορτίου LLM Θερμοκρασία: Υψηλότερες τιμές δίνουν πιο δημιουργικά/τυχαία δεδομένα, χαμηλότερη δίνει πιο συνεπή αποτελέσματα HubContexts: Καθορίστε τα συμφραζόμενα που ξεκινούν αυτόματα όταν η εφαρμογή ξεκινήσει
Αν φτιάχνετε ένα πραγματικό ταμπλό και θέλετε να το χρησιμοποιήσετε κατά τη διάρκεια της ανάπτυξης, ορίστε ένα παράδειγμα αντίδρασης:
import * as signalR from '@microsoft/signalr';
const connection = new signalR.HubConnectionBuilder()
.withUrl('http://localhost:5116/hub/mock')
.withAutomaticReconnect()
.build();
connection.on('DataUpdate', (message) => {
if (message.context === 'stock-market') {
updateStockChart(message.data);
}
});
await connection.start();
await connection.invoke('SubscribeToContext', 'stock-market');
Όταν είστε έτοιμοι να μεταβείτε στην παραγωγή, απλά αλλάξτε το URL κόμβου. Η διεπαφή Signer (on() και invoke()) λειτουργεί με τον ίδιο τρόπο με την πραγματική backends.
Υπάρχουν καλές ψεύτικες βιβλιοθήκες δεδομένων εκεί έξω. Faker.js είναι εξαιρετική. Mockaroo κάνει μεγάλη δουλειά.
Το εργαλείο αυτό λύνει συγκεκριμένες προκλήσεις:
Είναι σχεδιασμένο για μια συγκεκριμένη ροή εργασίας: οικοδόμηση σε πραγματικό χρόνο UIs όταν χρειάζεστε ποικίλα, ρεαλιστικά δεδομένα χωρίς διαμόρφωση από πάνω.
Ο καλύτερος τρόπος για να καταλάβετε αυτό το εργαλείο είναι να το χρησιμοποιήσετε:
dotnet run --project LLMApihttp://localhost:5116Από εκεί, προσπαθήστε να δημιουργήσετε το δικό σας πλαίσιο με μια περιγραφή που ταιριάζει στις ανάγκες του έργου σας.
Το έφτιαξα αυτό επειδή συνέχιζα να τρέχω στο ίδιο πρόβλημα: χρειάζομαι ρεαλιστικά, αλλάζοντας δεδομένα για ντέμο και ανάπτυξη. Αν αντιμετωπίσετε αυτή την πρόκληση επίσης, ελπίζω αυτό το εργαλείο να βοηθήσει τη ροή της εργασίας σας.
Ξεκινώντας:
dotnet run --project LLMApi
Προκαθορισμένο URL: http://localhost:5116
Signer Hub: /hub/mock
Βασικές μέθοδοι:
SubscribeToContext(name) - Άρχισε να λαμβάνεις δεδομέναUnsubscribeFromContext(name) - Σταματήστε να λαμβάνετε δεδομέναΓεγονότα-κλειδιά:
DataUpdate - Έφτασαν νέα δεδομένα.Subscribed - Επιβεβαιώθηκε η συνδρομήUnsubscribed - Επιβεβαιώθηκε η ανυπόγραφη περιγραφή.Τα υπόλοιπα είναι απλά να εξερευνήσεις τι μπορείς να φτιάξεις μ' αυτό.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.