Do I want to use Remoting or just a Socket connection - c#

I'm writing code for a project that was initially written in VB6 and my partner and I are trying to slowly migrate it to .NET. In the mean time I need some feedback on how I should go about doing the following:
My users can run several instances the same program to help split several specific Messages sent to a server; a server that will IP Ban you if you send to many messages at one time. What I want to do is share these messages sent between the programs so that we can build a distributed messaging system to prevent an IP Ban - these programs are running on the same machine at the present. I'm trying to get my feet wet, so I've done several (no joke...) days worth of research and I came to the conclusion that I could write a DLL in C# .NET, incorporate the needed Interop to support COM, and have that DLL store commonly used Functions, Arrays, Etc. The function would also raise events on the VB6 program to send its messages which then the client program would send to the server its connected to.
My partner says I'm going about this the wrong way and that I should to create a Sever application that loads when the first stances of my program starts and distribute messages between my clients via Socket. This process seems like a lot of work.
I'm finding it all the more difficult because samples I've found on MSDN won't compile. If you know of a great example I'd really appreciate you posting it.

Don't use Remoting for new development. It has been deprecated in favor of WCF.
Use WCF instead. You can host a WCF service in any application, and it can communicate quite quickly and efficiently using binary over TCP/IP.

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)

Is it possible that we could communicate C++ program in linux to a C# program acting as server using Remote Method Invocation?

Is it possible to implement client/server communication between a C++ program (client program) running in linux OS with a C# program(server program) running in Windows using RMI implementation?Can anyone suggest any possible way...Any kind of helpful reference is welcome
You would need to go along the lines of Google Protobuf. It is available with C++ and C# as well.
A similar answer from MSDN
It does not matter if you send data from java,c++ or c#, when it goes
over the network it's just 1s and 0s. It's a matter of what you do
with it on the client/server side. So, be sure that the data that you
receive corresponds with the structure that you have (that you want to
deserialize to).
Sometimes you need to manually put the bits and bytes together to get
it all working out. However, there is something called "Protobuff"
that can help you get a common structure of the data that you send,
google it and read all about it.
You can implement client server with sockets and serialize/deserialize it using protobuf.
(MSDN link might help in solution)
I think message passing libraries would fit best in to this. Take a look at ZMQ for instance; they have binding for many languages found here
so you may have your event dispatcher in one language and listener in the other language. Also take a look at apache thrift
CORBA is one IPC mechanism that will provide the RPC mechanism that you are looking for.
Here is a link describing communication between C# server and JAVA client.
http://iiop-net.sourceforge.net/dnAdderRmiClient.html
At one of the companies I worked previously, it was used for communication between c++ and java programs in a client/server model.
They used a combination of ACE/TAO libraries.
http://www.cs.wustl.edu/~schmidt/TAO.html
I would recommend that you do not use remote method invocation for communication between a client and a server. In the nineteen-nineties we used to believe that RMI is a good idea, but since then we have realized that there are much better ways for communication between computers.
The most popular way is by using Web Services, and the easiest flavor of Web Services is RESTful Web Services. (Look them up.) This has the benefit of not caring at all whether the runtime environment of the client looks anything like the runtime environment of the server, as the case is with your setup, where your client is C++ on Linux and your server is C# on Windows.
Mozilla's XPCOM might be your bridge. There is also PyXPCOM. Realistically though the easiest way is to have an intermediate VBox. So you run a VBox instance (running Windows) on the linux machine and then use VBox API (from C++) to issue commands within VBox. So you end up with
Linux <--xpCom--> VBox <--COM--> Windows
When working over network it's protocol what matters, not the client/server.
In telecommunications, a communications protocol is a system of rules that allow two or more entities of a communications system to transmit information via any kind of variation of a physical quantity. These are the rules or standard that defines the syntax, semantics and synchronization of communication and possible error recovery methods.
Source Emphasis is mine.
So, in order to communicate your C++ client and C# server you need to choose or define protocol that will be used for communication.
Your protocol can be build above another protocol. For example, you can use HTTP for transportation purposes and define your protocol describing what syntax should be used for messages in HTTP requests and responses bodies. This will help you, because there're many ready-to-use solutions for HTTP communication.
Actually you will build your protocol based on another anyway. HTTP itself build above TCP. You'll need to choose whether it would be low level or high level protocols. They all have their pros and cons.
But you will have to deal with messaging between your client and server yourself.
As an alternative you can use some Remote Procedure Call(or RPC) solution:
Remote procedure call (RPC) is an inter-process communication that allows a computer program to cause a subroutine or procedure to execute in another address space (commonly on another computer on a shared network) without the programmer explicitly coding the details for this remote interaction.
So that means that you only have to follow guidelines how to build your client and server and all communication will be hidden and will look like as just calling object's method.
Source
Here's short list of possible RPC solutions:
Component Object Model with DCOM. Wiki: COM,DCOM. MSDN: COM, DCOM.
Simple Object Access Protocol. Wiki.
Windows Communication Foundation. Wiki. MSDN. SO(credits to Sanju for link).
To wrap it up:
It's not a problem that your client and server are in different environments and are developed using different platforms. You only have to build communications between them using either your own messaging system based on some protocol, or some RPC system.
We could just write a C# program to listen messages from a particular port and write another C++ client program to write message to that port.As thus we could communicate both application.

replacing MarshalByRefObject with safer option in C#

I've tried to find a solution at stackoverflow but can't seem to find one quite like mine so here it goes. I have a computer in the lab that is connected to various devices like pan/tilt units, cameras, and light sensors and has all their drivers installed. I have C# code on the lab computer that knows how to talk to the hardware. The C# code can set an exposure time, ask for a picture, get one back, and display it in a picture box. I can tell the pan/tilt to move to a location and have it respond when done. If I am in the lab, it all works just the way I want.
The problem is that I want it to feel like I am at the lab computer when I am really at another computer. Most likely, I will be running the code that is on the non lab computer from inside Visual Studio. The program running in the lab will not be running from Visual Studio. With Remoting, this is a piece of cake. Put the code that talks to the hardware into a class, use MarshalByRefObject along with an interface I create, add RegisterWellKnownServiceType and presto I can use GetObject to get a reference and control it like I was sitting at the computer in the lab. So I know that remoting will work.
However, remoting is being phased out for WCF not to mention its not real safe out in the real world. It appears to me that WCF is going to make a local copy (by value) of the remote object which means it will not be on the lab computer and therefore unable to interact with the hardware that is attached. Someday this lab computer and all the sensor equipment is going to be moved away and I will have to access it remotely using the internet. A couple of years ago I did this exact thing but I was using remoting. Since remoting is so insecure, how do I do this without using remoting? Does WCF not have something equivalent to MarshalByRefObject? If WCF only uses by value, then it seems like they are phasing something out without providing functionality to replace it. Is there a way to use remoting that is not insecure? Is there something else besides WCF I should use?
This may be long winded but I see lots of people get dinged for asking questions that aren't very clear so I am trying to be clear. If there is already a post that truly provides me the best answer to my question, I must first apologize for not finding it myself but ask that a link be provided so I can get the answer there.
It appears to me that WCF is going to make a local copy (by value) of
the remote object which means it will not be on the lab computer and
therefore unable to interact with the hardware that is attached
This is almost entirely incorrect. There is no "copying" being done across machines. In fact the whole terminology around the "remote object" no longer has much meaning with WCF.
There is no remote object, simply a service. The service exposes operations across it's boundary. Service consumers can call those operations. When a consumer calls an operation, that call passes into the service and can cause the state of the service to change (for example, to talk to some hardware devices).
The service can also send a response to the caller, which can then cause the caller state to change (for example, to display output from the hardware device).
In order to make this happen you first need to create a service definition. Then you need to host your service on the lab machine. Then you need to create a service client, which you can then use on your local machine to call the service operations.
(How to) handle the situation where the port connected to the hardware
on the lab computer fires a DataReceived event that needs to be picked
up by my application
This is a more complex requirement but yes, WCF supports duplex communications with it's clients.
When you are defining your service contract you can specify that consuming clients implement a callback contract. This forces clients to define a callback operation which is exposed over the communication channel between service and client, and which the service can then call to "push" information to the client.
You should have your service use the WSDualHttpBinding WCF channel binding, which will use port 80 in both directions, allowing this to go across the internet.

What's the best way for a C# Desktop client to connect to a remote MySQL Db?

I am just learning c#, and am programming a Windows client that collects temperature data from the computer and needs to send it to a remote linux mySQL Database.
I was going to program it directly in the c# client, but I want to learn more ways to do this and gain experience. And programming it directly would be less secure and most likely require an extra connector.
Can any of you advise me of other ways, or ways you would do this?
Any way to program a C# program that acts as a web-service on my linux mySQL Server? Where should I look/search to learn more about this. Is it called something special? Or maybe its not done in C#?
Should I program a php script that accepts HTTP SEND/GET requests from my C# Desktop client?
Any other way?
What way is most 'professional' in the real world? Trying to learn on my own! :D
FORMAT:
Windows Desktop: client programmed in C# That retrieves temp data and needs to send to server
Linux Server: Runs Apache and mySQL Server with a database already setup. Closed to outside Connections
My advice is to set up a web service to communicate with your windows client. Directly connecting to mysql server is ok if they both resident in a same lan, but if not, for example your windows client is running on some laptop travelling everywhere or even the mysql server permits local incoming connection only, your should set up a web service. Also the http connection can usually go through firewalls while connections over other ports are blocked.
php is a good way to do this. Since you are learning c#, you may want to use c# to do the server side programming as well, so why not give a try of mono?
Directly exposing a MySQL Server to the internet is strongly dicouraged, Additionally this gives you a rather coarse-grained set of access rights, that might not be enough for your application, so running some sort of server app is the right way to go.
With mono you can run a lot of .Net (and thus C#) based code on a Linux server just fine. Rule of thumb is: If it doesn't have a Winforms GUI and no P/Invoke it will work just fine. Ofcourse this needs mono on the server, which is not given on most commercial hosts.
Running the server in PHP makes it a lot more portable, but has a performance overhead. Additionally it doesn't allow for some of your busines logic objects to be implemented in a DLL assembly and used on both sides.
As for the protocol: Chose your poison. Rule of thumb again is, that predefined protocols such as SOAP tend to need a bit more work (and more learning in the first go), but on the long term tend to be more robust.
For your special use-case I'd personally go with a quick PHP based solution where the protocol is just a simple GET with a few parameters, one being the temperature(s) and the others authenticating the client.
If the temperature sensor generates events, then I would 'push' the data from the Windows box to the Linux box - this will save the latter checking often and finding no updates. However if you are just taking temperature samples, I would 'pull' the data from the Linux machine. Either way, if you want to use HTTP you will need a web service on either side.
Alternatively, you could just connect to your MySQL database remotely from C#, and write the data directly (no web service would then be required). That might be the quickest way to get this working.
The 'which is professional' question is subjective - all three options above are fine. Just make the code clear and concise :)

Service -> App Communication. Best method?

I'm developing some kind of server service who gets in action and stop on an specific range of time, I need to write a monitoring app to receive some status text sent from the service in the same local host.
It's the first time I need to comm between processes, I've been looking for some methods, wich do you believe is the best for this case? why? pros and cons for each one?
Remoting
Named pipes
Windows messages
local tcp connection
Database table log (I'm using a database so it's another option)
Datafile on disk
Edit:
I'm using .net 2 so the great wcf solution doesn't work for me :(
See this SO question:
C# IPC Best Practises
You almost certainly want to use WCF. This replaces other .Net technologies such as remoting. Also, if you use WCF:
Other clients could also subscribe to that status information in the future.
The service listening to status updates could be run on another physical box if you needed to scale out.
If you're really just looking for "status messages" - as opposed to an actual client app - then you can use Trace/Debug.Write* statements. DebugView will pick them up if it's running, and can also be used across hosts. And, of course, you can add other listeners via config file if you later wanted to save the messages.

Categories

Resources