Kuestenlogik.Bowire.Protocol.Dis.SisoGen
1.0.21
Prefix Reserved
dotnet tool install --global Kuestenlogik.Bowire.Protocol.Dis.SisoGen --version 1.0.21
dotnet new tool-manifest
dotnet tool install --local Kuestenlogik.Bowire.Protocol.Dis.SisoGen --version 1.0.21
#tool dotnet:?package=Kuestenlogik.Bowire.Protocol.Dis.SisoGen&version=1.0.21
nuke :add-package Kuestenlogik.Bowire.Protocol.Dis.SisoGen --version 1.0.21
Kuestenlogik.Bowire.Protocol.Dis
Bowire protocol plugin for IEEE 1278.1 Distributed Interactive Simulation (DIS).
Two paths into a DIS multicast group:
- Live discovery + entity-scoped streaming — point Bowire at a
dis://group:portURL and the workbench probes the group, surfaces every active entity as a service, and streams typed PDU envelopes (filtered to that entity, or to the whole exercise feed) into the workbench. - Mock replay —
DisMockEmitterplugs into Bowire's mock server so a captured PDU sequence can be re-broadcast on UDP at the original cadence. Use it for offline testing without a live exercise.
URL shapes
dis://239.1.2.3:3000 # standard multicast group + DIS port
dis://multicast # shortcut for 239.1.2.3 (default port)
239.1.2.3:3000 # bare host:port also accepted
The default group is 239.1.2.3 and the default port is 3000
(IEEE 1278 convention). Discovery listens for 3 seconds — long enough
to catch a heartbeat from every active entity, short enough that the
workbench feels responsive.
probeDurationis not configurable yet. The plugin declares the setting and the workbench renders it, but no value ever reaches the plugin: settings are stored in the browser and there is no channel back to the server. The control looks like it works, and does not. Tracked in Kuestenlogik/Bowire#640 and #21; until then, treat the probe window as fixed at 3 seconds.
Live discovery
Standalone:
bowire --url dis://239.1.2.3:3000
Embedded:
app.MapBowire(options =>
{
options.ServerUrls.Add("dis://239.1.2.3:3000");
});
DiscoverAsync joins the multicast group for the configured probe
window, observes every EntityState PDU it sees, and surfaces:
- one synthetic
Exerciseservice whosemonitorstream yields every PDU on the group (raw exercise feed) - one service per discovered entity, named after its
EntityId(<site>:<application>:<entity>) plus marking + entity-type info, whosemonitorstream yields only PDUs from that entity
Subscribing to a service opens a UDP socket on the same group and yields one JSON envelope per matched PDU. The envelope decodes the PDU header (kind, family, exercise id, timestamp) plus EntityState specifics (position, orientation, velocity, marking string, force id) when applicable; other PDU kinds surface header + raw bytes so they can still be hex-dumped in the workbench.
Mock replay
DisMockEmitter plugs into Bowire's mock server via
IBowireMockEmitter. Recordings tagged protocol: "dis" get
re-broadcast on the configured multicast group at the original
cadence:
| Metadata key (first DIS step) | Purpose | Default |
|---|---|---|
multicast-group |
UDP multicast destination | 239.1.2.3 |
port |
UDP port | 3000 |
ttl |
Multicast TTL — 1 keeps it on the local subnet |
1 |
Each step carries:
protocol: "dis"responseBinary— base64 of the raw PDU bytes (IEEE 1278 wire format)capturedAt— millisecond timestamp used for emission pacing- optional
metadata(only on the first DIS step — applied to the whole DIS sub-sequence)
Use bowire mock --recording my-exercise.bowire-recording.json
to start replay. --loop re-emits the sequence on repeat.
Sample
A runnable end-to-end sample lives under samples/Kuestenlogik.Bowire.Protocol.Dis.Sample — an ASP.NET Core host that replays the bundled convoy.bowire-recording.json capture as a live multicast stream so the DIS tab has something deterministic to subscribe to without a running exercise. Loops on EOF so the feed never goes quiet.
dotnet run --project samples/Kuestenlogik.Bowire.Protocol.Dis.Sample
Then point Bowire's DIS tab at the multicast group + port the replayer logs at startup (defaults to dis://239.1.2.3:3000).
Install
dotnet tool install -g Kuestenlogik.Bowire.Tool
bowire plugin install Kuestenlogik.Bowire.Protocol.Dis
Local development
This plugin lives in its own repo so the external-plugin distribution pipeline gets exercised end-to-end. For local dev against an unpublished core Bowire:
cd ../Bowire && dotnet pack -c Release— produces.nupkgs forKuestenlogik.BowireandKuestenlogik.Bowire.Mockunderartifacts/packages/.- This repo's
nuget.configadds that directory as a package source, sodotnet restore && dotnet build && dotnet testhere picks up the freshly-packed contract packages. - Smoke-test end-to-end by dropping the built plugin DLL into
~/.bowire/plugins/Kuestenlogik.Bowire.Protocol.Dis/(or whereverbowire --plugin-dirpoints) and running eitherbowire --url dis://239.1.2.3:3000for live discovery orbowire mock --recording dis-sample.jsonfor replay.
Once Bowire's core packages are on nuget.org, the local feed in
nuget.config becomes redundant — consumers resolve the dependencies
directly and this repo becomes a pure NuGet package.
Status
- Live discovery + entity-scoped PDU streaming: shipped. EntityState PDUs decode markings, entity types, force ids; other PDU kinds surface header + raw bytes for hex-dumping.
- Mock replay: shipped (raw byte replay only — the emitter doesn't re-decode; it ships the captured bytes verbatim).
- Composition with the UDP plugin:
run both at once for typed (
dis) plus raw-bytes (udp) views of the same group.
License
Apache-2.0 — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.21 | 99 | 9/7/2026 |
| 1.0.20 | 96 | 9/4/2026 |
| 1.0.19 | 90 | 9/4/2026 |
| 1.0.18 | 94 | 9/3/2026 |
| 1.0.17 | 104 | 8/26/2026 |
| 1.0.16 | 181 | 8/7/2026 |
| 1.0.15 | 119 | 7/17/2026 |
| 1.0.14 | 122 | 7/6/2026 |
| 1.0.8 | 136 | 6/21/2026 |
| 1.0.5 | 127 | 6/3/2026 |
| 1.0.4 | 116 | 5/25/2026 |
| 1.0.3 | 129 | 5/20/2026 |
| 1.0.2 | 131 | 5/11/2026 |
| 1.0.1 | 135 | 5/9/2026 |
| 1.0.0 | 119 | 5/2/2026 |