MV10 / mv10.github.io

McGuireV10's personal blog
MIT License
4 stars 2 forks source link

A Simple Multi-Client WebSocket Server - Forty Years of Code #46

Open utterances-bot opened 4 years ago

utterances-bot commented 4 years ago

A Simple Multi-Client WebSocket Server - Forty Years of Code

Learn from this simple websocket server with realistic features.

https://mcguirev10.com/2019/01/15/simple-multi-client-websocket-server.html

mvAtSpoonRead commented 4 years ago

Jon, this is incredibly useful stuff. The code just worked right away -- thank you very much. Your explanations are also very helpful.

Thanks again for sharing this with the world. Appreciate it much, it is very good work!

PeterHuberStrub commented 4 years ago

Hy, I Iike your article. I have an application using Blazor. In the Context.WebSockets I find, the path value is _Blazor For my Clients ( IPC - Systems ) and also another Server I need other Websockts. Do know a way to realize this? Peter

MV10 commented 4 years ago

@PeterHuberStrub Do you mean that your Blazor server needs to also handle web socket requests? I'm not sure that's possible, since Blazor uses SignalR internally, which is web socket-based (at least partially). I would guess that SignalR would intercept the socket upgrade request before your own code could handle it.

I vaguely recall an issue about a plan to expose Blazor's internal SignalR for use by the Blazor application but I haven't used SignalR so I didn't pay much attention.

I wonder if it would be possible to write a piece of middleware that ran before SignalR in the processing pipeline? You'd need a way to identify which clients your middleware should upgrade versus passing it through so SignalR could answer so that Blazor would work properly.

If you find a solution, I'd be interested in hearing how you solved this.

PeterHuberStrub commented 4 years ago

Hi,

First, thank you for your prompt answer. I didn’t think to get an answer so fast. It’s clear that I would tel you if I have an answer for the problem. I thank you also for your published solution. I think, the solution is very near.

Second, I am, like you also an programmer with a long history. I began at the Uiveristy of Basel (Switzerland) , 23 Years old. This was 1971 ( calculate ). But I like to realize real projects. The one on which I work now is for a railway Company.

Third : Here I have multiple Users about 50 ) , multiple IPC’s ( about 250 all over the country ) and 2 Servers from the Railway Company. With the IPC’s and the Servers of the Railway Company I hace to exchage data with WebSocket’s.

The User Interface is a Web Solution. Here I use Blazor on the server Side. Blazor uses SignalR and SignalR also uses Websocket Connetctions under the hood.

I am more or less free to select an Port number for the Websocket Port to the IPC’s and tot he tot he Servers. I think it should be possible to dedicate a channel ( ports ) for Razor and other ports for the IPC’s and the two servers.

When I start your solution I get the following:

WS2020.Startup: Information: Configure 3 Request Path: /lib/bootstrap/dist/js/bootstrap.bundle.min.js WS2020.Startup: Information: Configure 3 Request Path: /_framework/blazor.server.js WS2020.Startup: Information: Configure 3 Request Path: /Bilder/sbb.jpg [2020-08-08T18:38:52.107Z] Information: Normalizing '_blazor' to 'https://localhost:44310/_blazor'. WS2020.Startup: Information: Configure 3 Request Path: /_blazor/negotiate WS2020.Startup: Information: Configure 3 Request Path: /_blazor WS2020.Startup: Information: Configure 4 Request Path: /_blazor [2020-08-08T18:39:06.251Z] Information: WebSocket connected to wss://localhost:44310/_blazor?id=bRfapv6BcILXtkbNQ-E1xw. Error: Invalid input for MessagePack hub protocol. Expected an ArrayBuffer or Buffer. at e.parseMessages (https://localhost:44310/_framework/blazor.server.js:15:42144) at e.processIncomingData (https://localhost:44310/_framework/blazor.server.js:1:17071) at e.connection.onreceive (https://localhost:44310/_framework/blazor.server.js:1:10276) at WebSocket.i.onmessage (https://localhost:44310/_framework/blazor.server.js:1:38091) Der Thread 0x3a3c hat mit Code 0 (0x0) geendet. Der Thread 0x548c hat mit Code 0 (0x0) geendet. Der Thread 0x2bfc hat mit Code 0 (0x0) geendet.

Now, I exclude

        //  add our custom middleware to the pipeline

And I the Blazor works

WS2020.Startup: Information: Configure 3 Request Path: /lib/bootstrap/dist/css/bootstrap.min.css WS2020.Startup: Information: Configure 3 Request Path: /js/site.js WS2020.Startup: Information: Configure 3 Request Path: /_framework/blazor.server.js WS2020.Startup: Information: Configure 3 Request Path: /Bilder/sbb.jpg [2020-08-08T18:46:12.217Z] Information: Normalizing '_blazor' to 'https://localhost:44310/_blazor'. WS2020.Startup: Information: Configure 3 Request Path: /_blazor/negotiate WS2020.Startup: Information: Configure 3 Request Path: /_blazor WS2020.Startup: Information: Configure 4 Request Path: /_blazor [2020-08-08T18:46:25.826Z] Information: WebSocket connected to wss://localhost:44310/_blazor?id=OyFbIr1pfAV0JX-Eaklg3w. WS2020.Startup: Information: Configure 3 Request Path: /Bilder/sbb.jpg Der Thread 0x5bb8 hat mit Code 0 (0x0) geendet. Der Thread 0x58c8 hat mit Code 0 (0x0) geendet. Der Thread 0x9d0 hat mit Code 0 (0x0) geendet.

Perhaps you see the problem.

Thank you.

Peter Huber

Von: Jon McGuire notifications@github.com Gesendet: Samstag, 8. August 2020 10:55 An: MV10/mv10.github.io mv10.github.io@noreply.github.com Cc: Peter Huber-Strub peter.huber-strub@outlook.com; Mention mention@noreply.github.com Betreff: Re: [MV10/mv10.github.io] A Simple Multi-Client WebSocket Server - Forty Years of Code (#46)

@PeterHuberStrubhttps://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FPeterHuberStrub&data=02%7C01%7C%7C6ec21535fc594a4eecc008d83b78ac95%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637324736752434924&sdata=bXZiEDXqc9Xu4p3wWqfkMDLa%2BFIGC0Zg5KdTUDnhkLg%3D&reserved=0 Do you mean that your Blazor server needs to also handle web socket requests? I'm not sure that's possible, since Blazor uses SignalR internally, which is web socket-based (at least partially). I would guess that SignalR would intercept the socket upgrade request before your own code could handle it.

I vaguely recall an issue about a plan to expose Blazor's internal SignalR for use by the Blazor application but I haven't used SignalR so I didn't pay much attention.

I wonder if it would be possible to write a piece of middleware that ran before SignalR in the processing pipeline? You'd need a way to identify which clients your middleware should upgrade versus passing it through so SignalR could answer so that Blazor would work properly.

If you find a solution, I'd be interested in hearing how you solved this.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMV10%2Fmv10.github.io%2Fissues%2F46%23issuecomment-670846971&data=02%7C01%7C%7C6ec21535fc594a4eecc008d83b78ac95%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637324736752444918&sdata=6pv6i%2FJX3KIk2WyMWVPhNvHRw4DOTUSVIvjiJD5nm8o%3D&reserved=0, or unsubscribehttps://eur06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAC47Z5WQ5COCJVHZWRXFXWDR7UHEVANCNFSM4LSC3EWQ&data=02%7C01%7C%7C6ec21535fc594a4eecc008d83b78ac95%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637324736752444918&sdata=9pCOI3PW4QLLtPAFmo6Bu5Dgwd0Mj3HAwj6lRWCpF5o%3D&reserved=0.

MV10 commented 4 years ago

With that ratio (50 users, 150 IPCs) I'm guessing the Blazor user sessions aren't what needs web socket communications. Can you just run a second ASP.NET Core site dedicated to your web socket services on that same server but listening on the other port?

PeterHuberStrub commented 4 years ago

Hi

Thank for your answer.

I have different possibilities:

The first : Communicate with the IPC – Clients via an second site, and writing/reading the datas to/from the Database. So, the main Buisness logic should be on this Solution. Then, with the other Site I would communicate with the users. Here also I have some logic behind. The question to answer is, how this two sites communicate with each other. Surely, we have the common Database. It’s no so fast an not event triggered.

The second: Rewrite the pages, ther will be no Blazor any more.

Thank fort he discussion. I think I will also ask this question in github.

I wish you a beautiful Sunday.

Peter

Von: Jon McGuire notifications@github.com Gesendet: Sonntag, 9. August 2020 12:24 An: MV10/mv10.github.io mv10.github.io@noreply.github.com Cc: Peter Huber-Strub peter.huber-strub@outlook.com; Mention mention@noreply.github.com Betreff: Re: [MV10/mv10.github.io] A Simple Multi-Client WebSocket Server - Forty Years of Code (#46)

With that ratio (50 users, 150 IPCs) I'm guessing the Blazor user sessions aren't what needs web socket communications. Can you just run a second ASP.NET Core site dedicated to your web socket services on that same server but listening on the other port?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FMV10%2Fmv10.github.io%2Fissues%2F46%23issuecomment-671034312&data=02%7C01%7C%7C750a3462929a4230e09608d83c4e5160%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637325654347339148&sdata=2Nt2rTO%2BVOJd4VBX51Je%2BvSDlGJmDjsQVKTv2rb0WOE%3D&reserved=0, or unsubscribehttps://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAC47Z5S7KM6FAG3AXFT2UMTR7Z2LTANCNFSM4LSC3EWQ&data=02%7C01%7C%7C750a3462929a4230e09608d83c4e5160%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637325654347349145&sdata=uIC56Uw6y6sYi%2BwZ9yYhZtmbL0gNeISftbOgmPVQWyI%3D&reserved=0.

MV10 commented 4 years ago

It seems MS supports the use of SignalR by your own code in Blazor now. This article is about client-side Blazor (WASM) but there are issues like the second link discussing Blazor Server usage.

https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&tabs=visual-studio

https://github.com/dotnet/aspnetcore/issues/20932

TarrahArshad commented 3 years ago

thank you for good article i will implement hub websocket client hub for manage many websocket client i implemented one app winform for hub and for each ws client console app my question is i can merg to single app with list of ws client ?

MV10 commented 3 years ago

@TarrahArshad yes, but you'll have to be careful with thread context so that you don't deadlock the UI (use ConfigureAwait(false)). For more information, see this FAQ.

haingo1958 commented 3 years ago

Dear Mr. Jon, Your article is very useful for understanding how to use completely WebSockets. Thanks a lot for sharing this with the World. I am wondering whether you would tell me why your code of examples does not work in Microsoft Visual Studio Community 2019 (Version 16.9.4) but receiving "ERROR: undefined/ SOCKET CLOSED" while running your ChannelWSServer as well as KestrelWebSocketServer, and receiving "... Exception WebSocketException: Unable to connect to the remote server..." while running your WebSocketClient. Thank you very much in advance!

MV10 commented 3 years ago

@haingo1958 with the Channel versions, there isn't really a good reason to use the non-Channel versions, but any combination of one server and one client from the repository is working normally (VS Community 16.10).

Are you saying you're trying to run the Kestrel example and the Channel server example at the same time? That won't work, they're both trying to listen on port 8080 (see the UseUrls call in Startup.cs).

haingo1958 commented 3 years ago

No, I am not. First, I did run "KestrelWebSocketServer" by Microsoft Visual Studio Community 2019 (Version 16.9.4). Then, I ran "WebSocketClient". I will try some other ways. Afterward, I can request something more. Thanks once again!

haingo1958 commented 3 years ago

I did run your WebSocketExample.csproj by Microsoft Visual StudioCommunity 2019. It worked very well. I assume that the code can be developed for real applications that are similar to MQTT and chat projects. However, I am not familiar with WebSockets. Please tell me how to develop the code for applications, which at first the WebSocket server will send a message to a client as http://localhost:8080 in your WebSocketExample. Thank you very much indeed in advance!

WarlockD commented 2 years ago

Any idea what canceling does in ReciveAsync? Does it lose the data or just give it back on next call?

MV10 commented 2 years ago

@WarlockD My guess is that you'd lose the data but I don't know for sure. There are very few safeguards in any of this.