4

I know about projects like Edge.js which allow for C# and Node.js connectivity, but I'm talking about something different. Is there a library for C#, that allows you to build scalable, non-blocking I/O, single threaded, async event servers in C#, similar to the servers you can build with Node.js? A library that also has the unique event model of Node.js, single threaded for user code, multi threaded for file/network events and native code (correct me if I'm wrong). Of course I know about ASP and WCF, and OSS projects like this, but I'm looking for something that gives you performance comparable to Node.js, a kind of Node.js port to C#. Do you know of any such library, and what would it take to build it?

Single threaded or multi threaded?

If you want a single threaded managed process that does all its work using APC and completion ports, you are going to have to hand code it. Building it would be risky and tricky. -- Sam Salton

Obivously, being single threaded makes code easier to write since you don't need to work with locks and mutexes. There's just one thread reading/modifying program state data which keeps things simple. All calculations occur on seperate threads and return to the main thread when the results are ready. All file/network events branch out and return to the main thread after the op is complete.

Related but different questions:

  1. Non-blocking single threaded web server
  2. Minimal web server
  3. Single threaded async events

Probably useful projects:

  1. ALE comes the closest to what I want, syntax similar to Node.js
  2. Manos de mono, a single threaded server for C#
  3. A message loop in C#, that processes events on a single thread
  4. Wrappers for Libuv in C# (1, 2)
  5. Anna for HTTP requests only (no binary), syntax similar to Node.js
Community
  • 1
  • 1
Robin Rodricks
  • 110,798
  • 141
  • 398
  • 607
  • 1
    "Is there a library for C#, that allows you to build scalable, non-blocking I/O, single threaded, async event servers in C#, similar to the servers you can build with Node.js?" Why would you want to write it in an event-based fashion when you can use async/await to write more readable asynchronous code? ;) – Jon Skeet Feb 26 '14 at 09:21
  • 1
    Sounds to me like you are trying to make a hammer work like a knife, just bite the bullet and write your app in node. – James Feb 26 '14 at 09:23
  • FYI - async/await does not block. – James Feb 26 '14 at 09:24
  • @Geotarget would it though? Node is effectively just javascript, there are tons of C# to JS converters [out there](http://scriptsharp.com/). Also, you could leverage edge to bridge the gap (I am currently doing this in my app). *"The node.js nested event handler system looks easier to manage"* - I agree, it is, which is why if you *really* want to leverage all the functionality you describe you really want to port your code to Node. – James Feb 26 '14 at 09:27
  • Unfortunately I don't know the intricacies of the CLI to give you a detailed answer on that, however, there are libraries that allow you to effectively host the V8 engine in .NET (if that's what you are after) like [Javascript.NET](http://javascriptdotnet.codeplex.com/) – James Feb 26 '14 at 09:31
  • Continued on chat - http://chat.stackoverflow.com/rooms/48451/discussion-between-geotarget-and-james – Robin Rodricks Feb 26 '14 at 10:02
  • You could look at https://github.com/jfromaniello/Anna (it's just an experiment) – Daniel Little May 05 '14 at 01:41

1 Answers1

1

I already posted this to your first related question, which may answer your question as well:

Here is an open-source example written in VB.NET and C#:

https://github.com/perrybutler/dotnetsockets/

It uses Event-based Asynchronous Pattern (EAP), IAsyncResult Pattern and thread pool (IOCP). It will serialize/marshal the messages (messages can be any native object such as a class instance) into binary packets, transfer the packets over TCP, and then deserialize/unmarshal the packets at the receiving end so you get your native object to work with. This part is somewhat like Protobuf or RPC.

It was originally developed as a "netcode" for real-time multiplayer gaming, but it can serve many purposes. Unfortunately I never got around to using it. Maybe someone else will.

The source code has a lot of comments so it should be easy to follow. Enjoy!

perry
  • 266
  • 1
  • 6
  • "Never got around to using it" = "Never debugged it and never used in production code?" – Robin Rodricks Aug 20 '14 at 13:15
  • I'm no expert in the way Node works, but I was looking for a system that could let you write callbacks inside callbacks, like you do in Node. Does your system allow for that? – Robin Rodricks Aug 20 '14 at 13:16
  • Never used in production. I will commit the newest code later today, which includes a re-factoring of the binary protocol into an HTTP protocol, as I have found a renewed interest, challenge and fun in doing so. Right now the framework can host a WordPress site using php-cgi, but I have been working on the performance surrounding high concurrency of many php-cgi processes (100, 1000 or 10000 simultaneous requests) when compared to Apache's in-process mod_php. Also, thanks for asking about it. If you want something more complete or ready for prime time you might check out Nito Async or SignalR. – perry Aug 20 '14 at 18:47
  • Concerning callbacks inside callbacks - e.g. doAsync1{doAsync2{doAsync3}} - APM and EAP have been superseded by TAP in .NET 4.0 which natively supports _continuations_ - e.g. Task.ContinueWith(callback) - similar to how Node.js manages "callback hell" with _promises_. Once the HTTP protocol can handle various sites properly, I'll switch over to TAP. While my answer is certainly not a Node.js to C# port, it does implement the patterns you mentioned. A [few benchmarks](http://glassocean.net/benchmarking-node-js-apache-and-net-sockets/) have put this project back on my radar. – perry Aug 20 '14 at 21:12
  • I need binary, do you mean with your refactoring you don't support binary protocols anymore? – Robin Rodricks Aug 21 '14 at 14:44
  • I'd like to make both protocols available. I put aside the binary code to focus on the HTTP code for stress testing purposes and it looks like the protocols are easily interchangeable within the same async model. Because of the major code juggling right now, I've decided to hold off from committing this latest dev snapshot until I can bring together both protocols in a not so silly way, since only the HTTP protocol is patched in at the moment. For the meantime, you might just have a look at the git repo which still has the binary protocol patched in. – perry Aug 21 '14 at 16:32