I'm developing a small multiplayer game, and currently the game server runs in a c# console application.
This limits me because:
the server gets stuck whenever I even start a text select in the console. If I even accidentally touch the console, the server gets stuck and I'm left shocked that the client is stuck somewhy, whereas it gets timed-out as soon as I right click the console and the select is canceled
I'm limited with supplying user input to the server. Say, I want to implement server commands, I have a great system I've written that handles pub-sub messages that I can use, and I just don't have any way to easily send those messages, since the server is console based and I can't rely on console input, when there's a lot of output to the console, and the client (which can publish those messages as well) is XNA base, and there's no easy way to implement a console on the client side (which would be an awesome thing to do, and would somehow solve some of my problems if I found a good library for XNA consoles).
I have several options to choose from -
WPF - I can write the server in WPF instead of a ConsoleApplication. This would give me somehow nice GUI, and it would be relatively easy to integrate since the majority of the code is a library and I wouldn't even need to export events, since I would be able to use my pub-sub system for the events.
Web - I have this picture in my mind - I run an executable which starts a local server, and it would just run in the background, people would be able to connect regularly, but I would be able to access a web page, and control the server through it. It would of course be a different port than the game server itself (I assume), and I would be able to control the server (send commands, kick players, restart rounds, and so on) through it.
What I'm here for, is for your suggestions, first of all. What do you find more suitable, pros and cons.
And if we're talking about a web-based server, what's the most standard way of doing that? I mean... mostly for raising a server, and how the website would communicate with it.
Thanks for reading, and thanks in advance for the advises!
Easiest would probably be to use something like Nancy (which is super simple to use) to process REST commands. You can add a Nancy webhost project to your solution and run it alongside your server, reusing your pub/sub architecture. Bonus, you can then use Nancy for certain client services that may not work as well on the server.
This is in fact similar to what we're doing with out XNA game, except Nancy also talks directly to clients, alongside the server, to serve up certain cpu or database bound data that isn't performance critical. We use redis to handle the pub/sub communication between the Nancy hosts and server instances.
Related
I have a WPF application running on a computer which is connected to a local network and there is a special device connected to this computer which is controlled by the application. Is there any easy way to migrate the GUI (WPF XAML) to another computer connected to the same network so that the GUI and BL stay coupled?
I have been looking into WCF but there are quite some limitations which would make it time consuming to adapt WCF to my situation. WCF would work perfectly if it could handle both properties (not supported at all) and events in one ServiceContract.
No, there is no simple way to do that.
If your GUI and BL are running on different machines, then you have to implement special code to perform network communications between apps (i.e. GUI and BL are two different apps), and if GUI and BL are tightly coupled, it's almost impossible and pointless to do so (network-related code would contain service contracts tremendous in size and remoting would consume large amount of time, making UI interaction slow and painful) - it should be refactored.
There is, however, a workaround for your problem - you can run your app on machine with both BL and GUI, then show that GUI on different machine: RemoteDesktop or RemoteApp (https://technet.microsoft.com/en-us/library/cc755055.aspx) could help with that.
An easy way? No.
You can, as you noted, use WCF. You could also use SignalR, a message bus, standard TCP sockets, or a number of other technologies.
None of these however will give you the absolute transparency you seem to desire. They all work off the concept that you are going to invoke a method on the server, and it may or may not return data. In the case of TCP, you send data and may get data back. You don't simply access/change a property or listen to an event (SignalR and WCF do support server->client invocation, which isn't exactly the same thing as an event, but it can work like one).
I think you need to look at implementing a standard client/server model, inconvenient as you may believe it to be.
I'm an amateur programmer working on a pet project of mine and I would like some pointers on how to make a C# server application. Here's the general idea:
A client connects to the server application, which in turn fetches the necessary information from a mysql database and sends it back to the client to be displayed and wait for the next action.
I got the idea of making something like this after seeing a somewhat old IBM AS400 mainframe running a warehouse management system, and I though: "Hey, I could try developing a small version of this with a nice UI that doesn't look like it stepped out of a time machine!"
I searched around and used the tcplistener class to communicate between the server and client and managed to send some calls and responses using one thread per client. However I've read that this is not scalable for a large number of clients...
Am I looking at this problem the wrong way and I should try something else? Any input will be appreciated
You don't need to deal with TCP directly for this - WCF (Windows Communication Foundation) was written to abstract all the low level stuff from you.
Check this link out for a good example of how to create a client/server application, it has an entry level explanation, some code and a downloadable project...
http://www.codeproject.com/Articles/16765/WCF-Windows-Communication-Foundation-Example
You can find plenty of information about WCF elsewhere on the internet and here on SO.
It is a very large topic, but the situation you have described is pretty simple - so I doubt you will have problems following the example.
I'm Currenty writing a server architecture and came across this as well: faily easy to solve.
You're right, using 1 thread per client is not effiecient and is a huge waste or resources! The way around that is Thread Pooling. There are loads of different ways to do this but the way I chose to implement it on my server was to add every connection to a queue and then have x number of threads (which you can easily increase or decrease to handle demand) simply dequeue a connection, process it, then enqueue it again.
Of course using WCF will make life easier for you and will speed things up drastically but where's the challange in that!
I need to write a program that will communicate with other .NET programs ... but also a legacy VFP program over TCP. I need to choose a fairly simple TCP message format that the VFP programmer can use. It could be as simple as a sequence of small XML blobs delimited by... I dunno, a null character? Whatever.
I need to choose between TcpListener/TcpClient and WCF. I started researching WCF but its architecture seems opaque and built-in Visual Studio templates are heavily biased toward making "web services" that act like a sort of RPC mechanism, but require a special "host" or web server that is external to the application. And Microsoft's 6-stage tutorial makes WCF sound pretty cumbersome (involving code generators, command-line and XML crap just to remotely subtract or multiply two numbers).
I want a self-contained app (no "host"), I want control of the wire protocol, and I want to understand how it works. WCF doesn't seem to facilitate these things, so I abandoned it in factor of TcpListener/TcpClient.
However, the program is to serve as an intermediary between a single (VFP) server and many (.NET) clients, and there will be communication in both directions and across different connections. Using TcpListener and TcpClient, the work of juggling the connections and threads is getting a bit messy, I have no experience with IAsyncResult, and I'm not just not confident in my code quality.
So I would like to solicit opinions again: should I still consider WCF instead? If yes, can you point me toward answers to the following questions?
Where in the web is a good explanation of WCF's architecture? Or do I need a book?
How is bi-directional communication done in WCF, where either side (of a single TCP connection) can send a message at any time?
How can I get past all the web-services and RPC mumbo-jumbo, and control the wire protocol?
In WCF, how do I shut down the app cleanly, closing all connections in parallel without hacky Thread.Abort() commands?
If no, how can I set up my code (that uses TcpListener/TcpClient/NetworkStream) so that I can read a message from a NetworkStream, but also accept requests from other connections, shut down cleanly at any time, and avoid wasting CPU time to poll queues and NetworkStreams that are inactive?
The short answer: go with WCF. While there's a good amount of tooling and code-generation and other bells and whistles around it, there's nothing that is preventing you from setting up everything in code (you can define your contracts, set the endpoints up, etc. all in code).
For your specific questions:
WCF Architecture - This is pretty basic, and it should get you up and running relatively quickly.
What you are looking for is duplex services. The NetTcpBinding allows for duplex services out-of-the-box (although you can do it with HTTP, you need a specific binding).
If you want to control the wire format, you will want to create a custom encoder. However, I have to strongly recommend against it. You want to create an XML file with null character to delineate separate messages? There's no need for that, the nature of XML is that you can create child elements to perform the appropriate grouping; there's no limit to how many elements you can nest. There's really no need for this.
Simply shutting down the ServiceHost by calling Close, this will allow all outstanding requests to complete, and then shut down gracefully. If you really want to tear down without concern, then call Abort.
In the end, I'd strongly recommend that you not use the NetTcpBinding; VFP will have a difficult time consuming the protocol. However, if you use an HTTP-based protocol, there are always tools that VFP can easily use to make the call and consume the contents (assuming you stick with XML).
Just to tack on about a common on using DCOM, VFP can utilize DCOM, but needs to be done with CreateObjectEx()... the only big difference is you need to know the GUID of the class instance you are connecting to on whatever server it is connecting to, AND the machine name its going to connect to.
Then the remote object does its work via exposed functions, but VFP calling it from some other machine on the network treats it as if the function was being performed locally and gets whatever the return values are.
I've done DCOM with VFP even as far back as 10 yrs ago for an insurance company...
I'm working with an application, and I am able to make C# scripts to run in this environment. I can import DLLs of any kind into this environment. My problem is that I'd like to enable communication between these scripts. As the environment is controlled and I have no access to the source code of the application, I'm at a loss as to how to do this.
Things I've tried:
File I/O: Just writing the messages that I would like each to read in .txt files and having the other read it. Problem is that I need this scripts to run quite quickly and that took up too much time.
nServiceBus: I tried this, but I just couldn't get it to work in the environment that I'm dealing with. I'm not saying it can't be done, just that I can't get it done.
Does anyone know of a simple way to do this, that is also pretty fast?
Your method of interprocess communication should depend on how important it is that each message get processed.
For instance, if process A tells process B to, say, send an email to your IT staff saying that a server is down, it's pretty important.
If however you're streaming audio, individual messages (packets) aren't critical to the performance of the app, and can be dropped.
If the former, you should consider using persistent storage such as a database to store messages, and let each process poll the database to retrieve its own messages. In this way, if a process is terminated or loses communication with the other processes temporarily, it will be able to retrieve whatever messages it has missed when it starts up again.
The answer is simple;
Since you can import any DLL into the script you may create a custom DLL that will implement communication between the processes in any way you desire: shared memory, named pipe, TCP/UDP.
You could use a form of Interprocess Communication, even within the same process. Treat your scripts as separate processes, and communicate that way.
Named pipes could be a good option in this situation. They are very fast, and fairly easy to use in .NET 3.5.
Alternatively, if the scripts are loaded into a single AppDomain, you could use a static class or singleton as a communication service. However, if the scripts get loaded in isolation, this may not be possible.
Well, not knowing the details of your environment, there is not much I can really offer. You are using the term "C# scripts"...I am not exactly sure what that means, as C# is generally a compiled language.
If you are using normal C#, have you looked into WCF with Named Pipes? If your assemblies are running on the same physical machine, you should be able to easily and quickly create some WCF services hosted with the Named Pipe binding. Named pipes provide a simple, efficient, and quick message transfer mechanism in a local context. WCF itself is pretty easy to use, and is a native component of the .NET framework.
Since you already have the File I/O in place you might get enough speed by placing it on a RAM disk. If you are polling for changes today a FileSystemWatcher could help to get your communication more responsive.
You can use PipeStream. Which are fast than disk IO as they are done using main memory.
XMPP/Jabber is another appraoch take a look at jabber.net.
Another easy way is to open a TCP Socket on a predefined Port, connect to it from the other process and communicate that way.
It has become apparent that where I work needs, internally, a "notification system". The issue being that we are very spread out throughout multiple buildings and the bulk of the work force regularly keeps there email closed for hours at a time.
I need to create a simple way to be able to push out a message and have it "pop up" on everyones computer(or a single computer).
My first thought was to write a windows service that calls a winform/wpf app that resides on each computer that simply pops up with the message. Not sure how viable an idea that is but this is just brain-storming.
A different route, I thought, could be an app that resides in the systray on each computer that polls a db table and using the Query Notifications could pop up a message each time a new row is added. Then simply create an insanely basic app for writing a row to that table.
So, what I am asking is if any one else has walked this path. If so, how?
What things did you take into
consideration?
Are either of my ideas valid starting
points or are "egg and my face in
perfect alignment"?
Is there a different way that is even
simpler?
Thanks
Some simple requirements --> Must be "One Way" as I cannot give our user base a "chat" system. Must be, somewhat, hidden so as to discourage users shutting it off. A la system tray or service.
Wouldn't net send save you reinventing the wheel?
I've never done this but I've worked in a call-centre that did use something similar and they're insanely useful. I remember once when everyone got a message saying "does anyone know Mandarin? HELP ME!!" Brilliant. (Luckily someone did.)
Anyway your ideas are perfectly fine. Personally I'd do this as a client/server application. A windows forms or WPF application that sits in the systray could link to a server using a TCP/IP duplex connection using WCF. Perhaps get the client to register to certain groups depending on the department of the PC it's sitting on.
Then when someone wants to send a message they select which group it needs to go to (or all groups), the message hits the server which sends out to all connected clients, and the WPF app on the computer receives the message and pops it up. You don't even need a database except to store the users/groups, and the message history if you need to.
This might be a ridiculous answer but have you considered implementing a chat system? It's simple to implement and well tested.
Here are some possibilities:
http://messenger.softros.com/
http://en.wikipedia.org/wiki/Instant_messaging#User_base
Article on building your own:
http://www.computerworld.com/s/article/9002059/How_to_build_your_own_corporate_IM_system_
The easiest way to do this is to have a simple client on each machine polling a central service for alerts. Each alert should have a unique id so each client can deal with idempotency (you don't want the central service keeping tabs on which clients have "popped up").
I also recommend having a reasonably short lifespan for each alert, so the client only needs to know a very short list of alerts it has displayed and so if a machine was re-started, only a small history of alerts would be displayed.
With 300 subscribers, you'll want the polling to involve a nice long gap too - you don't really want 300 checks every 10 seconds - so you'll have to balance the technical desire for long gaps between checks with the business requirement to get an alert within a certain timeframe.
You could easily achieve this with a NET/TCP WCF service being polled by either a WINFORM / WPF application that is added as a start up program, or a windows service that then spawns a UI to display the notification.
I did something like this a long time ago to coordinate smoke breaks. I simply sent a broadcast packet out on the LAN at a specific port. Worked relatively well, although since anybody could broadcast and everybody would get a popup, it got abused a lot.
I would recommend you SPARK. We have same problem in my firm and finally decided to save time and do not reinventing the wheel and use existing (freeware) solution. SPARK does the job for us.
"Spark is an Open Source, cross-platform IM client optimized for businesses and organizations. It features built-in support for group chat, telephony integration, and strong security. It also offers a great end-user experience with features like in-line spell checking, group chat room bookmarks, and tabbed conversations."
If you cannot use / install existing IMs you might thing about implementing simple "chat" protocol in your app.
It is quite easy do that base on sockets and many articles available.
For example:
http://www.codeproject.com/KB/IP/TCPIPChat.aspx
http://www.codeproject.com/KB/miscctrl/SimpleMessenger.aspx?display=Print
If you need something advanced (eg. receive historical notification, users status management etc) you can consider using openSource Jabber API:
Eg http://www.codeproject.com/KB/gadgets/googletalk.aspx