mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-20 07:51:41 +02:00
ws1
This commit is contained in:
543
copilot/WebSockets/v1/WEBSOCKET_VISUAL_OVERVIEW.md
Normal file
543
copilot/WebSockets/v1/WEBSOCKET_VISUAL_OVERVIEW.md
Normal file
@@ -0,0 +1,543 @@
|
||||
# WebSocket Implementation - Visual Architecture Overview
|
||||
|
||||
## System Architecture Diagram
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ WireMock.Net Solution │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Abstraction Layer (WireMock.Net.Abstractions) │ │
|
||||
│ ├──────────────────────────────────────────────────────────┤ │
|
||||
│ │ • IRequestBuilder │ │
|
||||
│ │ ├─ WithPath(), WithHeader(), UsingGet(), ... │ │
|
||||
│ │ └─ WithWebSocketPath() [NEW] │ │
|
||||
│ │ └─ WithWebSocketSubprotocol() [NEW] │ │
|
||||
│ │ │ │
|
||||
│ │ • IResponseBuilder │ │
|
||||
│ │ ├─ WithStatusCode(), WithBody(), WithCallback() │ │
|
||||
│ │ └─ WithWebSocket() [NEW] │ │
|
||||
│ │ └─ WithWebSocketCallback() [NEW] │ │
|
||||
│ │ │ │
|
||||
│ │ • IWebSocketResponseBuilder [NEW] │ │
|
||||
│ │ ├─ WithMessage(string) │ │
|
||||
│ │ ├─ WithJsonMessage(object) │ │
|
||||
│ │ ├─ WithBinaryMessage(byte[]) │ │
|
||||
│ │ └─ WithTransformer() │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ ▲ │
|
||||
│ │ implements │
|
||||
│ │ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Implementation Layer (WireMock.Net.Minimal) │ │
|
||||
│ ├──────────────────────────────────────────────────────────┤ │
|
||||
│ │ │ │
|
||||
│ │ Request Building │ │
|
||||
│ │ ├─ Request.cs (core builder) │ │
|
||||
│ │ ├─ Request.With*.cs (HTTP extensions) │ │
|
||||
│ │ └─ Request.WithWebSocket.cs [NEW] │ │
|
||||
│ │ │ │
|
||||
│ │ Response Building │ │
|
||||
│ │ ├─ Response.cs (core builder) │ │
|
||||
│ │ ├─ Response.With*.cs (HTTP extensions) │ │
|
||||
│ │ ├─ Response.WithWebSocket.cs [NEW] │ │
|
||||
│ │ └─ WebSocketResponseBuilder.cs [NEW] │ │
|
||||
│ │ │ │
|
||||
│ │ Domain Models │ │
|
||||
│ │ ├─ RequestMessage, ResponseMessage (existing) │ │
|
||||
│ │ ├─ WebSocketMessage [NEW] │ │
|
||||
│ │ └─ WebSocketResponse [NEW] │ │
|
||||
│ │ │ │
|
||||
│ │ Mapping Management │ │
|
||||
│ │ ├─ MappingBuilder.cs │ │
|
||||
│ │ ├─ RespondWithAProvider.cs │ │
|
||||
│ │ └─ Mapping.cs │ │
|
||||
│ │ │ │
|
||||
│ │ Server Integration [NEW] │ │
|
||||
│ │ ├─ WireMockServer.cs (update for WebSocket) │ │
|
||||
│ │ ├─ WireMockMiddleware.cs (upgrade handler) │ │
|
||||
│ │ ├─ MappingMatcher.cs (WebSocket routing) │ │
|
||||
│ │ └─ WebSocketConnectionManager [NEW] │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ ▲ │
|
||||
│ │ │
|
||||
│ ┌──────────────────────────────────────────────────────────┐ │
|
||||
│ │ Integration Layers │ │
|
||||
│ ├──────────────────────────────────────────────────────────┤ │
|
||||
│ │ • WireMock.Net (extends Minimal) │ │
|
||||
│ │ • WireMock.Net.StandAlone (OWIN hosting) │ │
|
||||
│ │ • WireMock.Net.AspNetCore.Middleware (ASP.NET Core) │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Request Handling Flow (HTTP vs WebSocket)
|
||||
|
||||
### HTTP Request Flow
|
||||
|
||||
```
|
||||
Client Server
|
||||
│ │
|
||||
├──── HTTP Request ────>│
|
||||
│ │ Request.Create()
|
||||
│ │ .WithPath("/api")
|
||||
│ │ .UsingPost()
|
||||
│ │ Match request matchers
|
||||
│ │
|
||||
│<─── HTTP Response ────┤ Response.Create()
|
||||
│ │ .WithStatusCode(200)
|
||||
│ │ .WithBody(...)
|
||||
│ │
|
||||
└───── Connection closed
|
||||
```
|
||||
|
||||
### WebSocket Request Flow
|
||||
|
||||
```
|
||||
Client Server
|
||||
│ │
|
||||
├─ WebSocket Upgrade ──>│
|
||||
│ (HTTP with headers) │ Request.Create()
|
||||
│ │ .WithWebSocketPath("/ws")
|
||||
│ │ Match request matchers
|
||||
│ │
|
||||
│<─ 101 Switching ──────┤ Upgrade to WebSocket
|
||||
│ Protocols │
|
||||
│ │
|
||||
│ ◄─────── Message 1 ───│ WebSocketResponse
|
||||
│ │ .Messages[0]
|
||||
│ ◄─────── Message 2 ───│ .Messages[1]
|
||||
│ │ (delayed 500ms)
|
||||
│ ◄─────── Message 3 ───│ .Messages[2]
|
||||
│ │ (delayed 1000ms)
|
||||
│ │
|
||||
│ ◄─── Close Frame ─────│ .WithClose(1000)
|
||||
│ │
|
||||
└───── Connection closed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Model Diagram
|
||||
|
||||
```
|
||||
HTTP Request/Response Models WebSocket Models
|
||||
═══════════════════════════════════ ═══════════════════════════
|
||||
|
||||
RequestMessage IWebSocketMessage
|
||||
├─ Path ├─ DelayMs
|
||||
├─ Method (GET, POST, etc.) ├─ BodyAsString
|
||||
├─ Headers ├─ BodyAsBytes
|
||||
├─ Body ├─ IsText
|
||||
├─ Query Params ├─ Id
|
||||
└─ Cookies └─ CorrelationId
|
||||
|
||||
ResponseMessage IWebSocketResponse
|
||||
├─ StatusCode ├─ Messages[]
|
||||
├─ Headers │ └─ IWebSocketMessage
|
||||
├─ Body ├─ UseTransformer
|
||||
├─ BodyAsJson ├─ TransformerType
|
||||
└─ ContentType ├─ CloseCode
|
||||
├─ CloseMessage
|
||||
├─ Subprotocol
|
||||
└─ AutoCloseDelayMs
|
||||
|
||||
WebSocketResponse
|
||||
(implements IWebSocketResponse)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Builder Pattern Hierarchy
|
||||
|
||||
```
|
||||
IRequestBuilder (interface)
|
||||
▲
|
||||
│
|
||||
└── Request (class)
|
||||
│
|
||||
├── Request.cs (core)
|
||||
├── Request.WithPath.cs
|
||||
├── Request.WithHeaders.cs
|
||||
├── Request.UsingMethods.cs
|
||||
├── Request.WithBody.cs
|
||||
├── Request.WithParam.cs
|
||||
└── Request.WithWebSocket.cs [NEW]
|
||||
├── WithWebSocketUpgrade()
|
||||
├── WithWebSocketPath()
|
||||
├── WithWebSocketSubprotocol()
|
||||
├── WithWebSocketVersion()
|
||||
└── WithWebSocketOrigin()
|
||||
|
||||
|
||||
IResponseBuilder (interface)
|
||||
▲
|
||||
│
|
||||
└── Response (class)
|
||||
│
|
||||
├── Response.cs (core)
|
||||
├── Response.WithStatusCode.cs
|
||||
├── Response.WithHeaders.cs
|
||||
├── Response.WithBody.cs
|
||||
├── Response.WithCallback.cs
|
||||
├── Response.WithTransformer.cs
|
||||
├── Response.WithProxy.cs
|
||||
├── Response.WithFault.cs
|
||||
└── Response.WithWebSocket.cs [NEW]
|
||||
├── WithWebSocket(builder)
|
||||
├── WithWebSocketMessage()
|
||||
├── WithWebSocketJsonMessage()
|
||||
├── WithWebSocketBinaryMessage()
|
||||
├── WithWebSocketCallback()
|
||||
├── WithWebSocketTransformer()
|
||||
├── WithWebSocketClose()
|
||||
├── WithWebSocketSubprotocol()
|
||||
└── WithWebSocketAutoClose()
|
||||
|
||||
|
||||
IWebSocketResponseBuilder (interface) [NEW]
|
||||
▲
|
||||
│
|
||||
└── WebSocketResponseBuilder (class) [NEW]
|
||||
├── WithMessage()
|
||||
├── WithJsonMessage()
|
||||
├── WithBinaryMessage()
|
||||
├── WithTransformer()
|
||||
├── WithClose()
|
||||
├── WithSubprotocol()
|
||||
├── WithAutoClose()
|
||||
└── Build() → IWebSocketResponse
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mapping Configuration Chain
|
||||
|
||||
```
|
||||
server.Given(request)
|
||||
↓
|
||||
IRespondWithAProvider
|
||||
├── AtPriority(int) ✓ HTTP & WebSocket
|
||||
├── WithTitle(string) ✓ HTTP & WebSocket
|
||||
├── WithDescription(string) ✓ HTTP & WebSocket
|
||||
├── WithPath(string) ✓ HTTP & WebSocket
|
||||
├── InScenario(string) ✓ HTTP & WebSocket
|
||||
├── WhenStateIs(string) ✓ HTTP & WebSocket
|
||||
├── WillSetStateTo(string) ✓ HTTP & WebSocket
|
||||
├── WithWebhook(...) ✓ HTTP & WebSocket
|
||||
├── WithTimeSettings(...) ✓ HTTP & WebSocket
|
||||
├── WithGuid(Guid) ✓ HTTP & WebSocket
|
||||
├── WithData(object) ✓ HTTP & WebSocket
|
||||
└── RespondWith(provider)
|
||||
↓
|
||||
IResponseProvider
|
||||
├── Response (HTTP)
|
||||
│ ├── WithStatusCode()
|
||||
│ ├── WithBody()
|
||||
│ ├── WithCallback()
|
||||
│ └── ...
|
||||
└── Response (WebSocket) [NEW]
|
||||
├── WithWebSocket()
|
||||
├── WithWebSocketCallback()
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fluent API Method Chains
|
||||
|
||||
### Simple Echo Server
|
||||
|
||||
```
|
||||
Request.Create()
|
||||
.WithWebSocketPath("/echo")
|
||||
↓
|
||||
Response.Create()
|
||||
.WithWebSocketCallback(async request =>
|
||||
new[] { new WebSocketMessage { BodyAsString = request.Body } }
|
||||
)
|
||||
```
|
||||
|
||||
### Stream with Multiple Messages
|
||||
|
||||
```
|
||||
Request.Create()
|
||||
.WithWebSocketPath("/stream")
|
||||
↓
|
||||
Response.Create()
|
||||
.WithWebSocket(ws => ws
|
||||
.WithMessage("Start", 0)
|
||||
.WithMessage("Middle", 500)
|
||||
.WithMessage("End", 1000)
|
||||
.WithClose(1000, "Complete")
|
||||
)
|
||||
```
|
||||
|
||||
### Dynamic with Templates
|
||||
|
||||
```
|
||||
Request.Create()
|
||||
.WithWebSocketPath("/api")
|
||||
.WithWebSocketSubprotocol("v2")
|
||||
↓
|
||||
Response.Create()
|
||||
.WithWebSocketSubprotocol("v2")
|
||||
.WithWebSocket(ws => ws
|
||||
.WithJsonMessage(new {
|
||||
user = "{{request.headers.X-User}}"
|
||||
})
|
||||
.WithTransformer()
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Transformer Integration
|
||||
|
||||
```
|
||||
WebSocket Response
|
||||
├─ Raw Content
|
||||
│ └─ "Hello {{user}}, timestamp: {{now}}"
|
||||
│
|
||||
└─ WithTransformer() [Enable Handlebars/Scriban]
|
||||
↓
|
||||
Transformer Engine (existing)
|
||||
├─ Request context injection
|
||||
├─ Helper methods (Math, String, etc.)
|
||||
└─ Custom helpers
|
||||
↓
|
||||
Transformed Content
|
||||
└─ "Hello Alice, timestamp: 2024-01-15T10:30:00Z"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Message Delivery Timeline
|
||||
|
||||
```
|
||||
Client connects → WebSocket Upgrade
|
||||
↓
|
||||
Message Queue Created
|
||||
↓
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ Message 1 (delayMs: 0) │
|
||||
│ ═════════════════════════════════════════════════════► │
|
||||
│ Sent immediately │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
↓ (wait 500ms)
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ Message 2 (delayMs: 500) │
|
||||
│ ═════════════════════════════════════► │
|
||||
│ Sent at T+500ms │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
↓ (wait 1000ms from start)
|
||||
┌──────────────────────────────────────────────────────────┐
|
||||
│ Message 3 (delayMs: 1000) │
|
||||
│ ═════════════════════════════► │
|
||||
│ Sent at T+1000ms │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
↓ (Close connection)
|
||||
Close Frame (1000, "Complete")
|
||||
↓
|
||||
Connection Closed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Organization
|
||||
|
||||
```
|
||||
src/WireMock.Net.Abstractions/
|
||||
│
|
||||
├── Models/
|
||||
│ ├── IWebSocketMessage.cs [NEW]
|
||||
│ ├── IWebSocketResponse.cs [NEW]
|
||||
│ └── ...existing models
|
||||
│
|
||||
├── Admin/Mappings/
|
||||
│ ├── WebSocketModel.cs [NEW]
|
||||
│ ├── ResponseModel.cs (extend for WebSocket)
|
||||
│ ├── RequestModel.cs (extend for WebSocket)
|
||||
│ └── ...existing models
|
||||
│
|
||||
├── BuilderExtensions/
|
||||
│ ├── IWebSocketResponseBuilder.cs [NEW]
|
||||
│ ├── WebSocketResponseModelBuilder.cs [NEW]
|
||||
│ └── ...existing builders
|
||||
│
|
||||
└── ...rest of abstractions
|
||||
|
||||
|
||||
src/WireMock.Net.Minimal/
|
||||
│
|
||||
├── Models/
|
||||
│ ├── WebSocketMessage.cs [NEW]
|
||||
│ ├── WebSocketResponse.cs [NEW]
|
||||
│ └── ...existing models
|
||||
│
|
||||
├── RequestBuilders/
|
||||
│ ├── Request.cs (update interfaces)
|
||||
│ ├── Request.WithWebSocket.cs [NEW]
|
||||
│ ├── Request.WithPath.cs
|
||||
│ ├── Request.WithHeaders.cs
|
||||
│ └── ...existing builders
|
||||
│
|
||||
├── ResponseBuilders/
|
||||
│ ├── Response.cs (update interfaces)
|
||||
│ ├── Response.WithWebSocket.cs [NEW]
|
||||
│ ├── WebSocketResponseBuilder.cs [NEW]
|
||||
│ ├── Response.WithStatusCode.cs
|
||||
│ ├── Response.WithBody.cs
|
||||
│ └── ...existing builders
|
||||
│
|
||||
├── Server/
|
||||
│ ├── WireMockServer.cs (update for WebSocket)
|
||||
│ ├── WireMockServer.Fluent.cs
|
||||
│ ├── MappingBuilder.cs
|
||||
│ ├── RespondWithAProvider.cs
|
||||
│ └── ...existing server code
|
||||
│
|
||||
├── Owin/
|
||||
│ ├── WireMockMiddleware.cs (add WebSocket upgrade)
|
||||
│ ├── MappingMatcher.cs (add WebSocket routing)
|
||||
│ └── ...existing OWIN code
|
||||
│
|
||||
└── ...rest of implementation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependency Graph
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ External Dependencies │
|
||||
├─────────────────────────────────────────┤
|
||||
│ • .NET Standard 2.0 / .NET Framework │
|
||||
│ • ASP.NET Core (WebSocket support) │
|
||||
│ • Newtonsoft.Json (serialization) │
|
||||
│ • Handlebars.Core (transformers) │
|
||||
│ • Scriban (transformers) │
|
||||
└──────────────────┬──────────────────────┘
|
||||
▲
|
||||
│
|
||||
┌──────────────────┴──────────────────────┐
|
||||
│ WireMock.Net.Abstractions │
|
||||
├──────────────────────────────────────────┤
|
||||
│ • Interfaces (IRequestBuilder, etc.) │
|
||||
│ • Models (RequestModel, ResponseModel) │
|
||||
│ • WebSocket abstractions [NEW] │
|
||||
└──────────────────┬──────────────────────┘
|
||||
▲
|
||||
│
|
||||
┌──────────────────┴──────────────────────┐
|
||||
│ WireMock.Net.Minimal │
|
||||
├──────────────────────────────────────────┤
|
||||
│ • Request builders │
|
||||
│ • Response builders │
|
||||
│ • WebSocket builders [NEW] │
|
||||
│ • Server core │
|
||||
│ • OWIN middleware │
|
||||
└──────────────────┬──────────────────────┘
|
||||
▲
|
||||
│
|
||||
┌──────────────────┴──────────────────────┐
|
||||
│ WireMock.Net (Full) │
|
||||
│ WireMock.Net.StandAlone (OWIN) │
|
||||
│ Application Code │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Test Coverage Areas
|
||||
|
||||
```
|
||||
Unit Tests (Request/Response Builders)
|
||||
├── WebSocketResponseBuilder tests
|
||||
│ ├── Message ordering
|
||||
│ ├── Delay handling
|
||||
│ ├── Transformer support
|
||||
│ └── Close frame handling
|
||||
├── Request builder tests
|
||||
│ ├── WebSocket path matching
|
||||
│ ├── Subprotocol matching
|
||||
│ └── Upgrade header validation
|
||||
└── Integration tests
|
||||
├── Client connection handling
|
||||
├── Message delivery
|
||||
├── Scenario state management
|
||||
├── Concurrent connections
|
||||
├── Connection timeout
|
||||
└── Error scenarios
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase Implementation Timeline
|
||||
|
||||
```
|
||||
Week 1: Phase 1-2 (Abstractions & Models)
|
||||
├─ Mon-Tue: Abstractions (IWebSocketMessage, etc.)
|
||||
├─ Wed: Domain Models (WebSocketMessage, etc.)
|
||||
└─ Thu: Code review & refinement
|
||||
|
||||
Week 2: Phase 3 (Request Builder)
|
||||
├─ Mon-Tue: Request.WithWebSocket.cs
|
||||
├─ Wed: Request matching tests
|
||||
└─ Thu: Integration with server
|
||||
|
||||
Week 3: Phase 4 (Response Builder)
|
||||
├─ Mon-Wed: Response.WithWebSocket.cs
|
||||
├─ Wed-Thu: WebSocketResponseBuilder
|
||||
└─ Fri: Message delivery tests
|
||||
|
||||
Week 4: Phase 5 (Server Integration)
|
||||
├─ Mon-Tue: WireMockMiddleware updates
|
||||
├─ Wed: Connection lifecycle management
|
||||
├─ Thu: Integration tests
|
||||
└─ Fri: Documentation & release prep
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: What's New vs What's Extended
|
||||
|
||||
```
|
||||
┌─────────────────────┬─────────────────────┬──────────────────┐
|
||||
│ Component │ New [NEW] │ Extended │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Request Builder │ Request. │ Request.cs │
|
||||
│ │ WithWebSocket.cs │ (interfaces) │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Response Builder │ Response. │ Response.cs │
|
||||
│ │ WithWebSocket.cs │ (interfaces) │
|
||||
│ │ WebSocketResponse │ │
|
||||
│ │ Builder.cs │ │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Domain Models │ WebSocketMessage.cs │ None │
|
||||
│ │ WebSocketResponse. │ │
|
||||
│ │ cs │ │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Admin API │ WebSocketModel.cs │ ResponseModel.cs │
|
||||
│ │ │ RequestModel.cs │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Server │ WebSocket │ WireMock │
|
||||
│ │ ConnectionManager │ Server.cs │
|
||||
│ │ [NEW] │ WireMock │
|
||||
│ │ │ Middleware.cs │
|
||||
├─────────────────────┼─────────────────────┼──────────────────┤
|
||||
│ Interfaces │ IWebSocketMessage │ IRequestBuilder │
|
||||
│ │ IWebSocketResponse │ IResponseBuilder │
|
||||
│ │ IWebSocketResponse │ │
|
||||
│ │ Builder │ │
|
||||
└─────────────────────┴─────────────────────┴──────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
This visual guide helps understand the architecture, data flow, and implementation scope of the WebSocket support proposal.
|
||||
Reference in New Issue
Block a user