();
38 |
39 | services.AddControllersWithViews();
40 | }
41 |
42 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
43 | {
44 | if (env.IsDevelopment())
45 | {
46 | app.UseDeveloperExceptionPage();
47 | }
48 | else
49 | {
50 | app.UseExceptionHandler("/Home/Error");
51 | }
52 |
53 | app.UseStaticFiles();
54 |
55 | // Proxy (Domain App) Client WebSocket - DMZ to API side connections
56 | app.UseProxyWebSockets();
57 |
58 | // User Agent WebSockets for Browsers
59 | app.UseNativeWebSockets();
60 |
61 | app.UseRouting();
62 |
63 | app.UseEndpoints(endpoints =>
64 | {
65 | endpoints.MapDefaultControllerRoute();
66 | });
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Home Page";
3 | }
4 |
5 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ConnectionId:
31 |
32 |
33 |
34 |
40 |
41 |
58 |
59 | Close
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | From
68 | To
69 | Data
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | @section scripts {
84 |
214 | }
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/Home/ReConnectTest.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Home Page";
3 | }
4 |
5 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ConnectionId:
31 |
32 |
33 |
34 |
40 |
41 |
58 |
59 | Close
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | From
68 | To
69 | Data
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | @section scripts {
84 |
85 |
214 | }
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/Process/Index.cshtml:
--------------------------------------------------------------------------------
1 | @*
2 | For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
3 | *@
4 | @{
5 | }
6 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/Shared/Error.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Error";
3 | }
4 |
5 | Error.
6 | An error occurred while processing your request.
7 |
8 | Development Mode
9 |
10 | Swapping to Development environment will display more detailed information about the error that occurred.
11 |
12 |
13 | Development environment should not be enabled in deployed applications , as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development , and restarting the application.
14 |
15 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewData["Title"] - Test App 1
7 |
8 |
9 |
10 |
28 |
29 | @RenderBody()
30 |
31 |
32 |
33 |
34 |
35 | @RenderSection("scripts", required: false)
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using WebClientTestApp
2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/WebClientTestApp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "CustomWebSocketCommandInvocator": {
3 | "ConnectorName": null,
4 | "WebSocketHostAddress": "localhost:7803"
5 | },
6 | "Logging": {
7 | "IncludeScopes": false,
8 | "LogLevel": {
9 | "Default": "Debug",
10 | "System": "Information",
11 | "Microsoft": "Information"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/wwwroot/_references.js:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | ///
5 | ///
6 | ///
7 |
--------------------------------------------------------------------------------
/test/WebClientTestApp/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetCoreStack/WebSockets/df14771cf84daeccd4ebf0889cdd49e79ea6e818/test/WebClientTestApp/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/test/WebClientTestApp/wwwroot/js/cookie.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * JavaScript Cookie v2.1.3
3 | * https://github.com/js-cookie/js-cookie
4 | *
5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6 | * Released under the MIT license
7 | */
8 | ; (function (factory) {
9 | var registeredInModuleLoader = false;
10 | if (typeof define === 'function' && define.amd) {
11 | define(factory);
12 | registeredInModuleLoader = true;
13 | }
14 | if (typeof exports === 'object') {
15 | module.exports = factory();
16 | registeredInModuleLoader = true;
17 | }
18 | if (!registeredInModuleLoader) {
19 | var OldCookies = window.Cookies;
20 | var api = window.Cookies = factory();
21 | api.noConflict = function () {
22 | window.Cookies = OldCookies;
23 | return api;
24 | };
25 | }
26 | }(function () {
27 | function extend() {
28 | var i = 0;
29 | var result = {};
30 | for (; i < arguments.length; i++) {
31 | var attributes = arguments[i];
32 | for (var key in attributes) {
33 | result[key] = attributes[key];
34 | }
35 | }
36 | return result;
37 | }
38 |
39 | function init(converter) {
40 | function api(key, value, attributes) {
41 | var result;
42 | if (typeof document === 'undefined') {
43 | return;
44 | }
45 |
46 | // Write
47 |
48 | if (arguments.length > 1) {
49 | attributes = extend({
50 | path: '/'
51 | }, api.defaults, attributes);
52 |
53 | if (typeof attributes.expires === 'number') {
54 | var expires = new Date();
55 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
56 | attributes.expires = expires;
57 | }
58 |
59 | // We're using "expires" because "max-age" is not supported by IE
60 | attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
61 |
62 | try {
63 | result = JSON.stringify(value);
64 | if (/^[\{\[]/.test(result)) {
65 | value = result;
66 | }
67 | } catch (e) { }
68 |
69 | if (!converter.write) {
70 | value = encodeURIComponent(String(value))
71 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
72 | } else {
73 | value = converter.write(value, key);
74 | }
75 |
76 | key = encodeURIComponent(String(key));
77 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
78 | key = key.replace(/[\(\)]/g, escape);
79 |
80 | var stringifiedAttributes = '';
81 |
82 | for (var attributeName in attributes) {
83 | if (!attributes[attributeName]) {
84 | continue;
85 | }
86 | stringifiedAttributes += '; ' + attributeName;
87 | if (attributes[attributeName] === true) {
88 | continue;
89 | }
90 | stringifiedAttributes += '=' + attributes[attributeName];
91 | }
92 | return (document.cookie = key + '=' + value + stringifiedAttributes);
93 | }
94 |
95 | // Read
96 |
97 | if (!key) {
98 | result = {};
99 | }
100 |
101 | // To prevent the for loop in the first place assign an empty array
102 | // in case there are no cookies at all. Also prevents odd result when
103 | // calling "get()"
104 | var cookies = document.cookie ? document.cookie.split('; ') : [];
105 | var rdecode = /(%[0-9A-Z]{2})+/g;
106 | var i = 0;
107 |
108 | for (; i < cookies.length; i++) {
109 | var parts = cookies[i].split('=');
110 | var cookie = parts.slice(1).join('=');
111 |
112 | if (cookie.charAt(0) === '"') {
113 | cookie = cookie.slice(1, -1);
114 | }
115 |
116 | try {
117 | var name = parts[0].replace(rdecode, decodeURIComponent);
118 | cookie = converter.read ?
119 | converter.read(cookie, name) : converter(cookie, name) ||
120 | cookie.replace(rdecode, decodeURIComponent);
121 |
122 | if (this.json) {
123 | try {
124 | cookie = JSON.parse(cookie);
125 | } catch (e) { }
126 | }
127 |
128 | if (key === name) {
129 | result = cookie;
130 | break;
131 | }
132 |
133 | if (!key) {
134 | result[name] = cookie;
135 | }
136 | } catch (e) { }
137 | }
138 |
139 | return result;
140 | }
141 |
142 | api.set = api;
143 | api.get = function (key) {
144 | return api.call(api, key);
145 | };
146 | api.getJSON = function () {
147 | return api.apply({
148 | json: true
149 | }, [].slice.call(arguments));
150 | };
151 | api.defaults = {};
152 |
153 | api.remove = function (key, attributes) {
154 | api(key, '', extend(attributes, {
155 | expires: -1
156 | }));
157 | };
158 |
159 | api.withConverter = init;
160 |
161 | return api;
162 | }
163 |
164 | return init(function () { });
165 | }));
--------------------------------------------------------------------------------
/test/WebClientTestApp/wwwroot/js/reconnecting-websocket.min.js:
--------------------------------------------------------------------------------
1 | !function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a});
2 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/AgentsWebSocketCommandInvocator.cs:
--------------------------------------------------------------------------------
1 | using NetCoreStack.WebSockets;
2 | using System.Threading.Tasks;
3 |
4 | namespace WebClientTestApp2
5 | {
6 | public class AgentsWebSocketCommandInvocator : IServerWebSocketCommandInvocator
7 | {
8 | private readonly IConnectionManager _connectionManager;
9 | public AgentsWebSocketCommandInvocator(IConnectionManager connectionManager)
10 | {
11 | _connectionManager = connectionManager;
12 | }
13 |
14 | public async Task InvokeAsync(WebSocketMessageContext context)
15 | {
16 | if (context.Command == WebSocketCommands.Connect)
17 | {
18 |
19 | }
20 |
21 | // Sending incoming data from Backend zone to the Clients (Browsers)
22 | await _connectionManager.BroadcastAsync(context);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace WebClientTestApp2
2 | {
3 | public static class Constants
4 | {
5 | public const string ConnectorName = "WebClientSPA2";
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace WebClientTestApp2.Controllers
4 | {
5 | public class HomeController : Controller
6 | {
7 | public IActionResult Index()
8 | {
9 | return View();
10 | }
11 |
12 | public IActionResult ReConnectTest()
13 | {
14 | return View();
15 | }
16 |
17 | public IActionResult About()
18 | {
19 | ViewData["Message"] = "Your application description page.";
20 |
21 | return View();
22 | }
23 |
24 | public IActionResult Contact()
25 | {
26 | ViewData["Message"] = "Your contact page.";
27 |
28 | return View();
29 | }
30 |
31 | public IActionResult Error()
32 | {
33 | return View();
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Hosting;
2 | using Microsoft.Extensions.Hosting;
3 | using System.Threading.Tasks;
4 |
5 | namespace WebClientTestApp2
6 | {
7 | public class Program
8 | {
9 | public static Task Main(string[] args)
10 | => BuildHost(args).RunAsync();
11 |
12 | public static IHost BuildHost(string[] args) => CreateHostBuilder(args).Build();
13 |
14 | public static IHostBuilder CreateHostBuilder(string[] args) =>
15 | Host.CreateDefaultBuilder(args)
16 | .ConfigureWebHostDefaults(webBuilder => webBuilder
17 | .UseStartup());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:17217/",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "WebClientTestApp2": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "launchUrl": "http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Startup.cs:
--------------------------------------------------------------------------------
1 | using Common.Libs;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.Configuration;
5 | using Microsoft.Extensions.DependencyInjection;
6 | using Microsoft.Extensions.Hosting;
7 | using Microsoft.Extensions.Logging;
8 | using NetCoreStack.WebSockets;
9 | using NetCoreStack.WebSockets.ProxyClient;
10 | using System;
11 |
12 | namespace WebClientTestApp2
13 | {
14 | public class Startup
15 | {
16 | public Startup(IConfiguration configuration)
17 | {
18 | Configuration = configuration;
19 | }
20 |
21 | public IConfiguration Configuration { get; }
22 |
23 | public void ConfigureServices(IServiceCollection services)
24 | {
25 | services.AddMemoryCache();
26 | services.AddSingleton();
27 |
28 | var connectorname = $"TestApp2-{Environment.MachineName}";
29 |
30 | // WebSocket - Proxy
31 | var builder = services.AddProxyWebSockets()
32 | .Register(connectorname, "localhost:7803");
33 |
34 | builder.Register(connectorname, "localhost:5000");
35 |
36 | // WebSockets for Browsers - User Agent ( javascript clients )
37 | services.AddNativeWebSockets();
38 |
39 | services.AddControllersWithViews();
40 | }
41 |
42 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
43 | {
44 | if (env.IsDevelopment())
45 | {
46 | app.UseDeveloperExceptionPage();
47 | }
48 | else
49 | {
50 | app.UseExceptionHandler("/Home/Error");
51 | }
52 |
53 | app.UseStaticFiles();
54 |
55 | // Proxy (Domain App) Client WebSocket - DMZ to API side connections
56 | app.UseProxyWebSockets();
57 |
58 | // User Agent WebSockets for Browsers
59 | app.UseNativeWebSockets();
60 |
61 | app.UseRouting();
62 |
63 | app.UseEndpoints(endpoints =>
64 | {
65 | endpoints.MapDefaultControllerRoute();
66 | });
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Home Page";
3 | }
4 |
5 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ConnectionId:
31 |
32 |
33 |
34 |
40 |
41 |
58 |
59 | Close
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | From
68 | To
69 | Data
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | @section scripts {
84 |
209 | }
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/Home/ReConnectTest.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Home Page";
3 | }
4 |
5 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | ConnectionId:
31 |
32 |
33 |
34 |
40 |
41 |
58 |
59 | Close
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | From
68 | To
69 | Data
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | @section scripts {
84 |
85 |
209 | }
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/Shared/Error.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Error";
3 | }
4 |
5 | Error.
6 | An error occurred while processing your request.
7 |
8 | Development Mode
9 |
10 | Swapping to Development environment will display more detailed information about the error that occurred.
11 |
12 |
13 | Development environment should not be enabled in deployed applications , as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development , and restarting the application.
14 |
15 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewData["Title"] - Test App 2
7 |
8 |
9 |
10 |
28 |
29 | @RenderBody()
30 |
31 |
32 |
33 |
34 |
35 | @RenderSection("scripts", required: false)
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using WebClientTestApp2
2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/WebClientTestApp2.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/WebSocketCommandInvocator.cs:
--------------------------------------------------------------------------------
1 | using Common.Libs;
2 | using Microsoft.Extensions.Caching.Memory;
3 | using NetCoreStack.WebSockets;
4 | using NetCoreStack.WebSockets.ProxyClient;
5 | using System.Collections.Generic;
6 | using System.Net.WebSockets;
7 | using System.Threading.Tasks;
8 |
9 | namespace WebClientTestApp2
10 | {
11 | public class WebSocketCommandInvocator : IClientWebSocketCommandInvocator
12 | {
13 | private readonly IConnectionManager _connectionManager;
14 | private readonly InMemoryCacheProvider _cacheProvider;
15 |
16 | public WebSocketCommandInvocator(IConnectionManager connectionManager, InMemoryCacheProvider cacheProvider)
17 | {
18 | _connectionManager = connectionManager;
19 | _cacheProvider = cacheProvider;
20 | }
21 |
22 | private Task InternalMethodAsync()
23 | {
24 | return Task.CompletedTask;
25 | }
26 |
27 | public async Task InvokeAsync(WebSocketMessageContext context)
28 | {
29 | if (context.MessageType == WebSocketMessageType.Text)
30 | {
31 |
32 | }
33 |
34 | if (context.MessageType == WebSocketMessageType.Binary)
35 | {
36 | var header = context.Header as Dictionary;
37 | if (header != null)
38 | {
39 | object key = null;
40 | if(header.TryGetValue(WebSocketHeaderNames.CacheItemKey, out key))
41 | {
42 | await Task.Run(() => _cacheProvider.SetObject(key.ToString(),
43 | context.Value,
44 | new MemoryCacheEntryOptions { Priority = CacheItemPriority.NeverRemove }));
45 | }
46 | }
47 | var length = context.Length;
48 | double size = (length / 1024f) / 1024f;
49 | context.Value = $"{size} MB <>";
50 | }
51 |
52 | // Sending incoming data from Backend zone to the Clients (Browsers)
53 | await _connectionManager.BroadcastAsync(context);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Debug",
6 | "System": "Information",
7 | "Microsoft": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/wwwroot/_references.js:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 | ///
4 | ///
5 | ///
6 | ///
7 |
--------------------------------------------------------------------------------
/test/WebClientTestApp2/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NetCoreStack/WebSockets/df14771cf84daeccd4ebf0889cdd49e79ea6e818/test/WebClientTestApp2/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/test/WebClientTestApp2/wwwroot/js/cookie.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * JavaScript Cookie v2.1.3
3 | * https://github.com/js-cookie/js-cookie
4 | *
5 | * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6 | * Released under the MIT license
7 | */
8 | ; (function (factory) {
9 | var registeredInModuleLoader = false;
10 | if (typeof define === 'function' && define.amd) {
11 | define(factory);
12 | registeredInModuleLoader = true;
13 | }
14 | if (typeof exports === 'object') {
15 | module.exports = factory();
16 | registeredInModuleLoader = true;
17 | }
18 | if (!registeredInModuleLoader) {
19 | var OldCookies = window.Cookies;
20 | var api = window.Cookies = factory();
21 | api.noConflict = function () {
22 | window.Cookies = OldCookies;
23 | return api;
24 | };
25 | }
26 | }(function () {
27 | function extend() {
28 | var i = 0;
29 | var result = {};
30 | for (; i < arguments.length; i++) {
31 | var attributes = arguments[i];
32 | for (var key in attributes) {
33 | result[key] = attributes[key];
34 | }
35 | }
36 | return result;
37 | }
38 |
39 | function init(converter) {
40 | function api(key, value, attributes) {
41 | var result;
42 | if (typeof document === 'undefined') {
43 | return;
44 | }
45 |
46 | // Write
47 |
48 | if (arguments.length > 1) {
49 | attributes = extend({
50 | path: '/'
51 | }, api.defaults, attributes);
52 |
53 | if (typeof attributes.expires === 'number') {
54 | var expires = new Date();
55 | expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
56 | attributes.expires = expires;
57 | }
58 |
59 | // We're using "expires" because "max-age" is not supported by IE
60 | attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
61 |
62 | try {
63 | result = JSON.stringify(value);
64 | if (/^[\{\[]/.test(result)) {
65 | value = result;
66 | }
67 | } catch (e) { }
68 |
69 | if (!converter.write) {
70 | value = encodeURIComponent(String(value))
71 | .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
72 | } else {
73 | value = converter.write(value, key);
74 | }
75 |
76 | key = encodeURIComponent(String(key));
77 | key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
78 | key = key.replace(/[\(\)]/g, escape);
79 |
80 | var stringifiedAttributes = '';
81 |
82 | for (var attributeName in attributes) {
83 | if (!attributes[attributeName]) {
84 | continue;
85 | }
86 | stringifiedAttributes += '; ' + attributeName;
87 | if (attributes[attributeName] === true) {
88 | continue;
89 | }
90 | stringifiedAttributes += '=' + attributes[attributeName];
91 | }
92 | return (document.cookie = key + '=' + value + stringifiedAttributes);
93 | }
94 |
95 | // Read
96 |
97 | if (!key) {
98 | result = {};
99 | }
100 |
101 | // To prevent the for loop in the first place assign an empty array
102 | // in case there are no cookies at all. Also prevents odd result when
103 | // calling "get()"
104 | var cookies = document.cookie ? document.cookie.split('; ') : [];
105 | var rdecode = /(%[0-9A-Z]{2})+/g;
106 | var i = 0;
107 |
108 | for (; i < cookies.length; i++) {
109 | var parts = cookies[i].split('=');
110 | var cookie = parts.slice(1).join('=');
111 |
112 | if (cookie.charAt(0) === '"') {
113 | cookie = cookie.slice(1, -1);
114 | }
115 |
116 | try {
117 | var name = parts[0].replace(rdecode, decodeURIComponent);
118 | cookie = converter.read ?
119 | converter.read(cookie, name) : converter(cookie, name) ||
120 | cookie.replace(rdecode, decodeURIComponent);
121 |
122 | if (this.json) {
123 | try {
124 | cookie = JSON.parse(cookie);
125 | } catch (e) { }
126 | }
127 |
128 | if (key === name) {
129 | result = cookie;
130 | break;
131 | }
132 |
133 | if (!key) {
134 | result[name] = cookie;
135 | }
136 | } catch (e) { }
137 | }
138 |
139 | return result;
140 | }
141 |
142 | api.set = api;
143 | api.get = function (key) {
144 | return api.call(api, key);
145 | };
146 | api.getJSON = function () {
147 | return api.apply({
148 | json: true
149 | }, [].slice.call(arguments));
150 | };
151 | api.defaults = {};
152 |
153 | api.remove = function (key, attributes) {
154 | api(key, '', extend(attributes, {
155 | expires: -1
156 | }));
157 | };
158 |
159 | api.withConverter = init;
160 |
161 | return api;
162 | }
163 |
164 | return init(function () { });
165 | }));
--------------------------------------------------------------------------------
/test/WebClientTestApp2/wwwroot/js/reconnecting-websocket.min.js:
--------------------------------------------------------------------------------
1 | !function(a,b){"function"==typeof define&&define.amd?define([],b):"undefined"!=typeof module&&module.exports?module.exports=b():a.ReconnectingWebSocket=b()}(this,function(){function a(b,c,d){function l(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,!1,!1,b),c}var e={debug:!1,automaticOpen:!0,reconnectInterval:1e3,maxReconnectInterval:3e4,reconnectDecay:1.5,timeoutInterval:2e3};d||(d={});for(var f in e)this[f]="undefined"!=typeof d[f]?d[f]:e[f];this.url=b,this.reconnectAttempts=0,this.readyState=WebSocket.CONNECTING,this.protocol=null;var h,g=this,i=!1,j=!1,k=document.createElement("div");k.addEventListener("open",function(a){g.onopen(a)}),k.addEventListener("close",function(a){g.onclose(a)}),k.addEventListener("connecting",function(a){g.onconnecting(a)}),k.addEventListener("message",function(a){g.onmessage(a)}),k.addEventListener("error",function(a){g.onerror(a)}),this.addEventListener=k.addEventListener.bind(k),this.removeEventListener=k.removeEventListener.bind(k),this.dispatchEvent=k.dispatchEvent.bind(k),this.open=function(b){h=new WebSocket(g.url,c||[]),b||k.dispatchEvent(l("connecting")),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","attempt-connect",g.url);var d=h,e=setTimeout(function(){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","connection-timeout",g.url),j=!0,d.close(),j=!1},g.timeoutInterval);h.onopen=function(){clearTimeout(e),(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onopen",g.url),g.protocol=h.protocol,g.readyState=WebSocket.OPEN,g.reconnectAttempts=0;var d=l("open");d.isReconnect=b,b=!1,k.dispatchEvent(d)},h.onclose=function(c){if(clearTimeout(e),h=null,i)g.readyState=WebSocket.CLOSED,k.dispatchEvent(l("close"));else{g.readyState=WebSocket.CONNECTING;var d=l("connecting");d.code=c.code,d.reason=c.reason,d.wasClean=c.wasClean,k.dispatchEvent(d),b||j||((g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onclose",g.url),k.dispatchEvent(l("close")));var e=g.reconnectInterval*Math.pow(g.reconnectDecay,g.reconnectAttempts);setTimeout(function(){g.reconnectAttempts++,g.open(!0)},e>g.maxReconnectInterval?g.maxReconnectInterval:e)}},h.onmessage=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onmessage",g.url,b.data);var c=l("message");c.data=b.data,k.dispatchEvent(c)},h.onerror=function(b){(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","onerror",g.url,b),k.dispatchEvent(l("error"))}},1==this.automaticOpen&&this.open(!1),this.send=function(b){if(h)return(g.debug||a.debugAll)&&console.debug("ReconnectingWebSocket","send",g.url,b),h.send(b);throw"INVALID_STATE_ERR : Pausing to reconnect websocket"},this.close=function(a,b){"undefined"==typeof a&&(a=1e3),i=!0,h&&h.close(a,b)},this.refresh=function(){h&&h.close()}}return a.prototype.onopen=function(){},a.prototype.onclose=function(){},a.prototype.onconnecting=function(){},a.prototype.onmessage=function(){},a.prototype.onerror=function(){},a.debugAll=!1,a.CONNECTING=WebSocket.CONNECTING,a.OPEN=WebSocket.OPEN,a.CLOSING=WebSocket.CLOSING,a.CLOSED=WebSocket.CLOSED,a});
2 |
--------------------------------------------------------------------------------