.NET WebSocket - 1.0


Compatibility: v2 v3 Express
What's new? Release Notes
ID: com.castsoftware.dotnet.websocket

Description

This extension should be installed when analyzing projects containing WebSocket applications, and you want to view a transaction consisting of Client and Server objects for WebSocket communication with their corresponding links.

In what situation should you install this extension?

You should install this extension if your .NET application uses WebSocket communication APIs.

Technology support

Library name Package/namespace Supported Version supported
.NET WebSockets (client) System.Net.WebSockets (ClientWebSocket, WebSocket) Up to .NET Framework 4.7.2 and .NET Core 1.0
.NET WebSockets (server via HttpListener) System.Net (HttpListenerContext.AcceptWebSocketAsync) Up to .NET Framework 4.7.2 and .NET Core 1.0
ASP.NET Microsoft.AspNetCore.Builder (MapExtensions.Map)
Microsoft.AspNetCore.WebSockets
Up to Microsoft.AspNetCore 10.0.1 and ASP.NET Core 1.0
WebSocket4Net WebSocket4Net Up to 0.15.2

Transactions

Transaction support is derived from metamodel concepts used to build CAST Imaging Blueprint and structural transaction flows. Entry Points start transactions; Exit Points include both output/boundary concepts and Data Entities manipulated by transactions.

Role Support Breakdown
Entry Point N/A No data available
Exit Point N/A No data available

ISO 5055 Structural Rules

Quality support is based on ISO 5055 structural rules available for the selected extension version.

Reliability Maintainability Security Performance Efficiency
N/A N/A N/A N/A

Dependencies

Some CAST extensions require the presence of other CAST extensions in order to function correctly. The .NET Websocket extension requires the following CAST extensions to be installed:

Download and installation instructions

For .NET applications using websocket libraries, the extension will be automatically installed. For upgrade, if the Extension Strategy is not set to Auto update, you can manually install the extension using the Application - Extensions interface.

What results can you expect?

Once the analysis/snapshot generation has completed, you can view the below objects and links created.

Objects

Icon Description Comment
.NET Server WebSocket An object to represent server WebSocket
.NET Client WebSocket An object to represent client WebSocket
.NET Unknown WebSocket Socket An object to represent server WebSocket when URI is not resolved
.NET Unknown Client WebSocket An object to represent client WebSocket when URI is not resolved
Link Type Source and Destination Link Supported Methods
callLink From .NET Server WebSocket / .NET Unknown Server WebSocket to Caller .NET method
System.NetSystem.Net.HttpListenerContext.AcceptWebSocketAsync
System.WebSystem.Web.Routing.Route.Route
Microsoft.AspNetCoreMicrosoft.AspNetCore.Builder.MapExtensions.Map
callLink From .NET Client WebSocket / .NET Unknown Client WebSocket to Caller .NET method
System.Net.WebSocketsSystem.Net.WebSockets.ClientWebSocket.ConnectAsync
WebSocket4NetWebSocket4Net.WebSocket.WebSocket
callLink From .NET Server WebSocket to event methods
System.Net.WebSocketsSystem.Net.WebSockets.WebSocket.ReceiveAsync
System.Net.WebSockets.ClientWebSocket.ReceiveAsync
System.Net.WebSockets.WebSocket.CloseAsync
System.Net.WebSockets.WebSocket.CloseOutputAsync
System.Net.WebSockets.ClientWebSocket.CloseOutputAsync
callLink From .NET Client WebSocket to event methods
WebSocket4NetWebSocket4Net.WebSocket.Open
WebSocket4Net.WebSocket.Opened.add
WebSocket4Net.WebSocket.MessageReceived.add
WebSocket4Net.WebSocket.Closed.add
WebSocket4Net.WebSocket.Error.add
callLink From .NET Client WebSocket to .NET Server WebSocket Linking is handled by Universal Linker

Code Examples

System.Net.WebSockets
WebSocketClientServer.cs
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketClientServer
{
    public class WebSocketClient
    {
        private const string ServerUri = "ws://localhost:8080/ws/";

        public async Task ConnectAndSendAsync()
        {
            using var client = new ClientWebSocket();
            await client.ConnectAsync(new Uri(ServerUri), CancellationToken.None);

            var message = Encoding.UTF8.GetBytes("Hello, WebSocket!");
            await client.SendAsync(
                new ArraySegment<byte>(message),
                WebSocketMessageType.Text,
                endOfMessage: true,
                CancellationToken.None);

            var buffer = new byte[1024 * 4];
            var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            await client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
        }
    }
}
WebSocketServer.cs
using System;
using System.Net;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

namespace WebSocketClientServer
{
    public class WebSocketServer
    {
        private const string ServerUri = "http://localhost:8080/ws/";

        public async Task StartAsync()
        {
            var listener = new HttpListener();
            listener.Prefixes.Add(ServerUri);
            listener.Start();

            var context = await listener.GetContextAsync();
            var wsContext = await context.AcceptWebSocketAsync(subProtocol: null);
            var webSocket = wsContext.WebSocket;

            var buffer = new byte[1024 * 4];
            var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            while (result.MessageType != WebSocketMessageType.Close)
            {
                await webSocket.SendAsync(
                    new ArraySegment<byte>(buffer, 0, result.Count),
                    result.MessageType,
                    result.EndOfMessage,
                    CancellationToken.None);

                result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            }

            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
        }
    }
}

WebSocket4Net
WebSocket4NetClientExample.cs
using System;
using WebSocket4Net;

public class WebSocket4NetClientExample
{
    private readonly WebSocket _webSocket;

    public WebSocket4NetClientExample(string serverUri)
    {
        _webSocket = new WebSocket(serverUri);

        _webSocket.Opened += OnOpened;
        _webSocket.Closed += OnClosed;
        _webSocket.Error += OnError;
        _webSocket.MessageReceived += OnMessageReceived;
    }

    public void Connect()
    {
        Console.WriteLine("Client: opening connection...");
        _webSocket.Open();
    }

    public void Disconnect()
    {
        Console.WriteLine("Client: closing connection...");
        _webSocket.Close();
    }

    private void OnOpened(object sender, EventArgs e)
    {
        Console.WriteLine("Client: connection opened");

        _webSocket.Send("Hello from client");
    }

    private void OnClosed(object sender, EventArgs e)
    {
        Console.WriteLine("Client: connection closed");
    }

    private void OnError(object sender, SuperSocket.ClientEngine.ErrorEventArgs e)
    {
        Console.WriteLine($"Client: error: {e.Exception.Message}");
    }

    private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
    {
        Console.WriteLine($"Client received: {e.Message}");
    }
}
Program.cs
using System;

public class Program
{
    public static void Main(string[] args)
    {
        var server = new WebSocketChatServer();
        server.StartAsync();

        var client = new WebSocket4NetClientExample("ws://localhost:9090/ws/chat/");
        client.Connect();
        client.Disconnect();
    }
}
WebSocketChatServer.cs
using System;
using System.Net;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

public class WebSocketChatServer
{
    private const string ServerUri = "http://localhost:9090/ws/chat/";

    public async Task StartAsync()
    {
        var listener = new HttpListener();
        listener.Prefixes.Add(ServerUri);
        listener.Start();

        var context = await listener.GetContextAsync();
        var wsContext = await context.AcceptWebSocketAsync(subProtocol: null);
        var webSocket = wsContext.WebSocket;

        var buffer = new byte[1024 * 4];
        var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

        while (result.MessageType != WebSocketMessageType.Close)
        {
            await webSocket.SendAsync(
                new ArraySegment<byte>(buffer, 0, result.Count),
                result.MessageType,
                result.EndOfMessage,
                CancellationToken.None);

            result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        }

        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
    }
}

Microsoft.AspNetCore
Startup.cs
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;

namespace AspNetCoreWebSocketApp
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.UseWebSockets();
            app.Map("/ws/echo", HandleEcho);
        }

        private static void HandleEcho(IApplicationBuilder app)
        {
            app.Run(async context =>
            {
                if (context.WebSockets.IsWebSocketRequest)
                {
                    using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
                    await Echo(webSocket);
                }
                else
                {
                    context.Response.StatusCode = 400;
                }
            });
        }

        private static async Task Echo(WebSocket webSocket)
        {
            var buffer = new byte[1024 * 4];
            var result = await webSocket.ReceiveAsync(new System.ArraySegment<byte>(buffer), CancellationToken.None);

            while (!result.CloseStatus.HasValue)
            {
                await webSocket.SendAsync(
                    new System.ArraySegment<byte>(buffer, 0, result.Count),
                    result.MessageType,
                    result.EndOfMessage,
                    CancellationToken.None);

                result = await webSocket.ReceiveAsync(new System.ArraySegment<byte>(buffer), CancellationToken.None);
            }

            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
    }
}
WebSocketClient.cs
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AspNetCoreWebSocketApp
{
    public class WebSocketClient
    {
        private const string ServerUri = "ws://localhost:5000/ws/echo";

        public async Task ConnectAndSendAsync()
        {
            using var client = new ClientWebSocket();
            await client.ConnectAsync(new Uri(ServerUri), CancellationToken.None);

            var message = Encoding.UTF8.GetBytes("Hello, ASP.NET Core WebSocket!");
            await client.SendAsync(
                new ArraySegment<byte>(message),
                WebSocketMessageType.Text,
                endOfMessage: true,
                CancellationToken.None);

            var buffer = new byte[1024 * 4];
            var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

            await client.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
        }
    }
}