Commit 7de3f478 authored by Sylvain Renault's avatar Sylvain Renault
Browse files

Websocket sample implementation.

parent 479c5c5b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ server/worldstorage/README.md

# all generated directories
wwwroot/
!wwwroot/ws.html
Attributes/
Authentication/
Converters/
+125 −0
Original line number Diff line number Diff line
//
// ARF - Augmented Reality Framework (ETSI ISG ARF)
//
// Copyright 2024 ETSI
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Last change: June 2024
//

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Net.WebSockets;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.SwaggerGen;

#pragma warning disable CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element
namespace ETSI.ARF.OpenAPI.WorldStorage.Services
{
    //
    // ETSI-ARF World Analysis WebSocket implementation
    // see also: https://learn.microsoft.com/de-de/aspnet/core/fundamentals/websockets?view=aspnetcore-5.0
    //
    public class WebSocketController : ControllerBase
    {
        [HttpGet("/ws")]
        public async Task Get()
        {
            if (HttpContext.WebSockets.IsWebSocketRequest)
            {
                using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();

                if (webSocket.State == WebSocketState.Open)
                {
                    // Response an OK message
                    await SendText(webSocket, "Hello, here is the ARF World Analysis services!");
                }
                await Echo(HttpContext, webSocket);
            }
            else
            {
                await HttpContext.Response.WriteAsync("ETSI-ARF World Analysis: Not a valid WebSocket request.");
                HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
            }
        }

        //
        // Send a line of text
        //
        private async Task SendText(WebSocket webSocket, string text)
        {
            // Response an OK message
            var message = text;
            var bytes = Encoding.UTF8.GetBytes(message);
            var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
            await webSocket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None);
        }

        //
        // Send the time all seconds
        //
        private async Task SendTime(WebSocket webSocket)
        {
            while (true)
            {
                var message = "Hello, my time is: " + DateTime.Now.ToLocalTime();
                var bytes = Encoding.UTF8.GetBytes(message);
                var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);

                if (webSocket.State == WebSocketState.Open)
                {
                    await webSocket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                else if (webSocket.State == WebSocketState.Closed || webSocket.State == WebSocketState.Aborted)
                {
                    break;
                }
                Thread.Sleep(1000);
            }
        }

        //
        // Echo incoming messages
        //
        private async Task Echo(HttpContext context, WebSocket webSocket)
        {
            var buffer = new byte[1024 * 4];

            // get the first data block
            WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            while (!result.CloseStatus.HasValue)
            {
                // test
                await SendText(webSocket, "Thanks, I got this message:");

                // echo the message back to the client
                await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);

                // get the next block
                result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
            }
            await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
        }
    }
}
#pragma warning restore CS1591 // Fehlendes XML-Kommentar fr ffentlich sichtbaren Typ oder Element

+9 −0
Original line number Diff line number Diff line
@@ -161,6 +161,15 @@ namespace ETSI.ARF.OpenAPI.WorldAnalysis
                app.UseHsts();
            }

            // ETSI-ARF Websocket implementation
            var webSocketOptions = new WebSocketOptions()
            {
                KeepAliveInterval = TimeSpan.FromSeconds(120),
            };
            //webSocketOptions.AllowedOrigins.Add("https://etsi.hhi.fraunhofer.de");
            //webSocketOptions.AllowedOrigins.Add("https://www.client.com");
            app.UseWebSockets();

            app.UseHttpsRedirection();
            app.UseDefaultFiles();
            app.UseStaticFiles();