Switching Client and Server roles on gRPC in .NET Apps? - c#

So I'm starting with the simple Greeter service from the VS2022 sample project template "ASP.NET Core gRPC Service", targeting .NET7, running on Windows. Name this side "A".
I was able to write a second console app (also .NET7) that connects as a gRPC client to that service, invoke the SayHello() rpc successfully and retrieve the expected response message. Name this side "B". So far, so good.
My scenario, however, is a bit different: I want the client B to connect to the server A and authenticate with the server (which is not part of the sample so far but I assume this will work fine as well). Then, the server A shall start acting as a gRPC client and the console-app-client B shall act as a gRPC server, i.e. I want them to switch roles (or establish another role if you like). The challenge is that I want the two parties to re-use the same TCP HTTP/2 connection that has already been established. So I'm looking for a way to create new instances of gRPC client/servers at runtime and provide them with the existing TCP connection. The reason why I need to do it this way are limitations coming from network security (the initial connection can only come B to A). I'm aware that by using streams I can make my server A send messages to B, but I'd prefer to have the full client/server support.
I saw a few discussions around the same question but the presented approaches are using GO as a language and it's hard for me to understand whether and how I can do the same in .NET7.
Possible? Thanks!

Related

Best Practices: Adding a CLI to Existing Windows Service in .NET / Core

I'm wondering if anyone has any recommendations for the best way to implement a command line interface to an existing Windows service.
Ideally, the following requirements can be met:
Supports .Net Core and works cross platform
Is self hosted (ie not a separate executable)
Is registered globally and available in any terminal (ie. > myApp doThis -please --prettyplease)
Can be piped through to a web interface for remote terminal access via existing web app
Is available via terminals on other local network devices
The big requirement is that this works cross platform and is not tied to Windows. Any recommendations are very much appreciated!!!
Questions that feature the phrase "what is the best" typically aren't a good fit for stackoverflow as they're subjective - there may be no right answer to your query, but maybe there will be some good ones.
One option that I've employed several times in the past is to implement something like a simple shell/command prompt, accessed via telnet. You simply open a listening socket (TcpListener) and accept text commands sent to it/write text to it, something like your first day's of programming, with console in and out stream printing. There are bucketloads of examples on the web of simple tcp servers so I won't provide any code here. In terms of your points:
Supports .Net Core and works cross platform
It's tcp based, this is intrinsic
Is self hosted (ie not a separate executable)
Starts when the app starts, hosted by the app, doesn't need any complex IPc
Is registered globally and available in any terminal (ie. > myApp doThis -please --prettyplease)
The firewall is probably the only thing stopping your remote device communicating
Call be piped through to a web interface for remote terminal access via existing web app
html5/web based implementations of telnet exist. Could also make a simple web interface out of it (treat the browser like telnet; Here's little difference between them, they both read and write tcp sockets, just the browser adds more text from the http protocol. You can filter that out and just get the interesting bit the user can vary (the URL))
Is available via terminals on other local network devices
Covered above
The last time I implemented this was on a server that was used by credit card terminals. It already had a listening socket and clients followed a strict protocol, so it was easy to detect when a message didn't match protocol and treat it as a command instead. The system grew to the point where the server was full remotely configurable via a simple telnet interface, new credit card ranges and routings could be added,debug printouts could be enabled and all traffic would be sent to the telnet client, certain card terminals could be monitored etc; it was nothin more than compsci101 stuff of command = streamreader.ReadLine(), if(command == "debug") Global.DebugLoggingStream = tcpWriterStream
It had a web interface too, based on HttpListener, that just provided a nicely formatted list of the most recent errors, some config settings etc.. some stuff is better on a web page in a table than in an 80char column format. Eventually I upgraded this to be more like the terminal; the user could end the URL with a command, the command would be carried out and the result put in an array. Each time the page was served he array was dumped, so it became a sort of command shell in itself, not requiring telnet. I kept the telnet interface because it was good for realtime debugging, watching messages as they happened etc but if you wanted to get really fancy, websockets exists today for that sort of thing.
Another thought struck me; perhaps most of this hard work has been done for you, if you can find a c# implementation of an irc server, paired with a web based irc client, it would provide a way to "chat" with your service (which is pretty much all a command shell is; a human having a text chat with a program)

Howto: SocketConnection in ASP.NET

Actually I'm using node.js and socket.io to establish a socket connection. For some reasons I need to replace the server part with an ASP.NET application. Therefore I have to replace the existing socket.IO-server with a suitable .NET pendant.
From my understanding socket.IO as well as SignalR use websockets. So can I replace the socket.io-server with a signalR-server without or with even minimal changes in the clients?
Actually I tried to setup a SignalR-Server using the following example http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server
I'm able to connect to the hub when I use the sample code mentioned there.
But I'm not able to connect to this server using socket.IO or websockets in nodeJS. Maybe because of the magic with the hubs.
So is there any solution for an easy to use .NET package, hosted in IIS, that allows secured websocket-connections or secure tcp-socket connections between clients and my server. This solution should be quite standard so I can use Java or Node or anything else on client side?

Reverse Connecting Sock5 Proxy server c#

I want to develop sock5 proxy server in c# which could make connections to client.
i.e in normal scenarios client or browser make connection to proxy server but i want the proxy server to connect to the client.
i googled a lot but could not find any code sample in c# or other language.
This sounds like a rather broad question, but generally I think what you are trying to do isn't "by definition possible". Socks5 is defined in RFC1928 (https://www.rfc-editor.org/rfc/rfc1928). It specifically relates to the 'client' connecting to the 'server'. In order for the proxy server to connect to the client, the client machine would have to have some form of service running and listening on a previously established port (assuming TCP/IP here). I suppose you could write some form of browser plugin or a service daemon to listen for server initiated connections; however, this wouldn't technically be 'socks5'. Having an open port (service) on your client open other security concerns, such as a connection from a machine claiming to be your server, or an outside machine requesting the proxy server to contact your client machine. Part of the trust model of these setups is the idea of client initiated actions. You may be trying to solve the wrong problem (i.e. you may need to reframe your problem in a different way).

Communication between C# clients which are behind router and Java server which is on public internet

I have a C# applications which acts like a client and it can be installed on any system which is directly connected to public internet (through data cards or port forwarding) or they can be behind router also (without port forwarding).
The other application which is developed using java acts like a server application which is on the public internet. Now, my java application wants to push a message to C# application which is behind router. Java application has the clients public and private (192.168.x.x) IP address. Java application is supposed to run 24x7.
So, now there are two options for me:
Whenever c# application starts it will establish a socket connection with java application and this socket connection will remain open till C# application gets closed.
Whenever Java application has something for C# application it will create a socket connection with C# application then it will push the message and then close the connection.
Now, with 1st option there is a problem that there will be lots of unnecessary connection since there can be thousands of client application and it may happen that on some day there will be nothing to push for some clients. and I don't know how to go for 2nd option.
What will be the right way to accomplish this task (option 1 or 2)?
Is UPnP protocol right for 2nd option? What are the open source UPnP libraries which has both the API's (C# and Java). I found one such called ohnet. Will it be a right thing for me? I didn't found a single small example for OhNet to test.
2) is not feasible if you don't have control over network configuration at the client end. It won't in general be possible for the server to make connections to the client if the client is behind any moderately secure firewall / router.
So you will in general have have to go for some variant of 1) where the client creates a connection to the server.
You don't necessarily have to keep the connection open though - it's always possible to get the client to poll the server periodically to check if there are any new updates.
If you want realtime updates to the client from the server then you will still need to keep a connection open. This isn't necessarily a problem if you use Java NIO you should be able to handle tens of thousands of simultaneous incoming connections relatively easily.
Using option 2, will you have to queue messages for your C# client until it connects? That could make your Java application run into out of memory problems if the C# application doesn't connect.
I would definitely use method 2 by adding a static route in the router (port forward). You should - however - ensure that the server behind the router is protected from the rest of your network (DMZ).
UPDATE:
Perhaps I have missed something here (method 1 or 2) :-) - but just to make it absolutely clear: It is always the client that should initiate the connection to the server. And yes, you could allow the client to request the server for updates on a regular basis.

Client-Server architecture

This topic has been discussed million times before, but let me clarify my needs:
I need a single server which controls a system and includes the necessary functions. Furthermore, there will be "n" Clients which represents only the HI/GUI and call server side functions. The server itself should be able to send data back to the clients and call client-side functions too (like shutdown, exit and so on...)
I have heard about duplex services/contracts (http://msdn.microsoft.com/en-us/library/ms731064.aspx), but I'm not sure how far I'll come with that.
How would you handle this?
I recently made a proof of concept app that made both the server and the client host a WCF service each. The client connects to the server and then in a handshake call, gives the server the connection information to allow the server create a separate connection back to the client. It worked a treat with multiple clients on network links from local lan to 64k line on remote sites at the same time.
You could use WCF, and host the service on the server in IIS, in the application on the client and let the client register it's endpoint on the server.

Categories

Resources