Windows Service Usage

17 views
Skip to first unread message

Christopher Meek

unread,
Mar 10, 2011, 8:34:14 AM3/10/11
to lidgren-network
Hey All,

I'm looking to use lidgren in a simple chat server. Now I've looked
at the samples in the lidgren source and have noticed the following,

- For winforms apps they use the Application_Idle handler combined
with the NativeMethods.AppStill Idle prop to manage running of the
lidgren message pump

- For console apps something similar is done via
Console.IsKeyAvailable

My question is then what would be the suggested equivalent within a
windows service application?

Jacob Rommann

unread,
Mar 10, 2011, 10:13:27 AM3/10/11
to lidgren...@googlegroups.com
I just used a simple timer in my test apps which worked great, but someone with more experience may have a better way.

Rabid

Matthew Overall

unread,
Mar 10, 2011, 11:05:17 AM3/10/11
to lidgren...@googlegroups.com

I would use a timer as well.

> --
> You received this message because you are subscribed to the Google Groups "lidgren-network" group.
> To post to this group, send email to lidgren...@googlegroups.com.
> To unsubscribe from this group, send email to lidgren-netwo...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/lidgren-network?hl=en.
>

Christopher Meek

unread,
Mar 10, 2011, 11:22:53 AM3/10/11
to lidgren-network
So, if we were looking at a more performance intensive application,
say a multiplayer game server (getting simple chat working is really a
stepping-stone for me) would this still be a valid approach?

On Mar 10, 4:05 pm, Matthew Overall <matthew.over...@gmail.com> wrote:
> I would use a timer as well.

Matthew Overall

unread,
Mar 10, 2011, 11:38:19 AM3/10/11
to lidgren...@googlegroups.com
Absolutely, I am not sure how well this will work but you could possibly setup your own Game Loop inside the windows service, I imagine since there is no UI to manage whatsoever you could do this very easily.

Create a Timer and attach your UpdateMethod() to its Tick event. Then at the end of every UpdateMethod(), call Timer.Tick() to recall the UpdateMethod.

If you are going to do a lot of logging to the eventviewer/log files I would throw those in a seperate thread so you don't slow down your update loop. 

Also, you will probably want to create a GameTimer class using the Timer & TimeSpan objects so you can calculate your movement, FPS, etc... (Never rely on the speed of the UpdateMethod to calculate movement since it will vary, always use an ElapsedTime)

Hope this helps, but this is something I have never tried before so let us know if that works for ya.

Matthew Overall

unread,
Mar 10, 2011, 11:42:28 AM3/10/11
to lidgren...@googlegroups.com
Sorry for the double post, but if you want help setting this up feel free to ask.
Message has been deleted

Christopher Meek

unread,
Mar 10, 2011, 12:00:43 PM3/10/11
to lidgren-network
I've just had a look at the NetPeer class and seen the
MessageReceivedEvent code. Would it be possible to therefore do
something like this...

// In the service code (pseudo code)
public void OnStart(...)
{
LaunchGameSimulation();
NetPeer peer = new NetPeer(configuration);
peer.MessageReceivedEvent += HandleMessage;
peer.Start();
}

public void HandleMessage(...)
{
// deal with the message; pass it through validation filters or
onto the game simulation etc.
}

On Mar 10, 4:42 pm, Matthew Overall <matthew.over...@gmail.com> wrote:
> Sorry for the double post, but if you want help setting this up feel free to
> ask.
>
> On Thu, Mar 10, 2011 at 9:38 AM, Matthew Overall
> <matthew.over...@gmail.com>wrote:
>
>
>
>
>
>
>
> > Absolutely, I am not sure how well this will work but you could possibly
> > setup your own Game Loop inside the windows service, I imagine since there
> > is no UI to manage whatsoever you could do this very easily.
>
> > Create a Timer and attach your UpdateMethod() to its Tick event. Then at
> > the end of every UpdateMethod(), call Timer.Tick() to recall the
> > UpdateMethod.
>
> > If you are going to do a lot of logging to the eventviewer/log files I
> > would throw those in a seperate thread so you don't slow down your update
> > loop.
>
> > Also, you will probably want to create a GameTimer class using the Timer &
> > TimeSpan objects so you can calculate your movement, FPS, etc... (Never rely
> > on the speed of the UpdateMethod to calculate movement since it will vary,
> > always use an ElapsedTime)
>
> > Hope this helps, but this is something I have never tried before so let us
> > know if that works for ya.
>
> > On Thu, Mar 10, 2011 at 9:22 AM, Christopher Meek <chris.mr.m...@gmail.com

Christopher Meek

unread,
Mar 10, 2011, 12:01:31 PM3/10/11
to lidgren-network
Now it's my turn to apologise for a double post, the game sim would
then be launched it it's own independent thread

Chris Cowherd

unread,
Mar 10, 2011, 12:06:51 PM3/10/11
to lidgren...@googlegroups.com, Christopher Meek
The MessageReceivedEvent is an AutoResetEvent, not a delegate.

You can have a thread waiting on the event (i.e.  peer.MessageReceivedEvent.WaitOne(); )

My advice would be not to get bogged down with worrying about the efficiencies at this point.  Do the most easy, reliable thing you can (no threading!) until you have performance issues.  Most of the time the bottlenecks are not where you think they would have been.

The timer idea is simple and will probably be the best for your chat server.  Don't forget that the timer may call you back on a different thread than the one that created it.

Matthew Overall

unread,
Mar 10, 2011, 12:08:01 PM3/10/11
to lidgren...@googlegroups.com
You might want to give that a shot, I have never used the MessageReceivedEvent so just swap it out for an application idle in one of the samples and let us know of the results.

Chris Cowherd

unread,
Mar 10, 2011, 12:09:18 PM3/10/11
to lidgren...@googlegroups.com, Christopher Meek
Slight correction, you probably should call the public method NetPeer::WaitMessage( );

It takes care of the call to WaitOne and also calls ReadMessage for you.

riki

unread,
Mar 10, 2011, 12:16:07 PM3/10/11
to lidgren-network
Hi,
I am afraid I don't understand the problem, maybe adding some code
that points out the issue would help me understand the question.
Anyway the App idle or isKeyAvailable are not needed, the later is
just an exit condition in the console demo!

For a real game server you would like to do a couple of things:
1. create a background thread looping forever (until the server
signals an exits) and accepting connections/new messages
2. decouple client/network/server speed from message transfer by
queueing all incoming traffic to some intermediate storage (queue,
list, whatever)
3. do the same as under 2. for outgoing traffic. For 'small load'
servers one loop can do both tasks but doing it right from start and
splitting into two tasks cant hurt.
4. never ever use timers! Use a loop which constantly checks for new
messages if data is arrived reads it as fast as possible, stores it
and serves immediately another client. You also don't want to have any
sleeps inside this loop, use a signal to wait on until something
arrives (depending on the lidgren version you have that might not be
available).
5. read 4. again .-)

You might want to check the 'The Borg Server' source:
under "\trunk\Source\Servers\WorldServer\" check the NetworkServer.cs
and MessageSender.cs.
Both files are rather small and easily understandable.


HTH
Riki
http://www.titanium.hr

please visit my projects:
http://www.borgserver.net/borg-world-server-layout
http://sourceforge.net/apps/phpbb/txnagameengine

Chris Cowherd

unread,
Mar 10, 2011, 12:30:54 PM3/10/11
to lidgren...@googlegroups.com, riki
Riki - Thanks for contributing your input!  I would respectfully disagree about timers.  For the general case of a game engine, sure, don't use a timer.  It doesn't have the resolution you need to pump messages.  He just wants to make a chat server to start though and for that its a perfectly acceptable solution.

Using a loop spinning on checking for available messages he will pretty much peg the CPU doing nothing.  Using a timer, you can get sufficient resolution and all the waiting is done in kernel mode leaving the CPU free for other things.

I would also make a comment regarding the storage of the messages.  If you have a look at the Lidgren internals, it is already queuing the messages for you as the arrive so you don't want to double this effort.  

A lot of people are really tempted to use a lot of threads, one for reading and handling messages and others for processing etc. but I have written some pretty high performance servers ( http://www.youtube.com/watch?v=kCp2-nfibzY) with Lidgren and I can tell you that there is a lot of wasted CPU time in this not to mention complexity, ease of debugging and safety.

By the way, I think the Borg server is very cool.  I've been following it for some time now.


Matthew Overall

unread,
Mar 10, 2011, 12:35:42 PM3/10/11
to lidgren...@googlegroups.com
I don't understand why you would NEVER EVER use timers, I personally don't agree but I don't want to take this off topic. 

Your game server is very impressive and I assume works great for you. However, Using timers will allow you to control the a FixedTimeStep rather than a never ending loop, which may be great for this scenario considering it is a simple chat server for a game. 60 FPS would be a good target for a game, 30 FPS would be more than sufficient for a chat server. 

I feel being able to control a target frame rate is necessary for most gameloops and has many advantages. Using timers will make this much easier and I see absolutely no downside to it.

riki

unread,
Mar 10, 2011, 12:57:31 PM3/10/11
to lidgren-network
Well its up to the OP to decide...my impression was that a chat is
just a first step - a proof of concept so to say. But that he wants a
real game server as a final result.

Regarding the threading stuff... that's such a large topic but just a
words:
- threading is not necessary a bad thing in terms of CPU usage (as
with everything else the implementation can be done very poor or very
good)
- threads are served from the .NET thread pool and multiple .NET
threads are actually executed by another (smaller) pool of system
threads - no 1:1 relation. So using background workers helps
conserving system resources.
- threads are cheap today since the CPU's have multiple cores - 4
hardware threads is something most common today while real server HW
has usually even more threads on disposal
- kernel waits are bad. why? too long story... its all about switching
contexts
- sleeps are bad cause they involve context switching as well
- timers are bad for the same reason and few more - you already named
one
- receving/sending threads do not hog any CPU time, they simply
process the data and wait on a signal (check the Borg Network Server
source to see what I mean). Of course mindless looping in circle would
hog a lot CPU but thats why the waitone is there.

Regarding the intermediate storage, that's just a must have for high
performance servers.
The only other option that crosses my mind would be hogging the
receiver loop with reading lidgren buffers, deserializing them an
invoking business logic. This can consume a considerable amount of
processing time during which all "other clients are waiting" (not
literally true, but the clients data is waiting unprocessed).

All the above and in my previous mail applies ONLY to high performance
and scalable server scenarios.
If the OP really wants just a simple chat between say 2-20 clients
than disregards all and I mean ***ALL*** my comments!
On Mar 10, 6:30 pm, Chris Cowherd <mad...@gmail.com> wrote:
> Riki - Thanks for contributing your input!  I would respectfully disagree
> about timers.  For the general case of a game engine, sure, don't use a
> timer.  It doesn't have the resolution you need to pump messages.  He just
> wants to make a chat server to start though and for that its a perfectly
> acceptable solution.
>
> Using a loop spinning on checking for available messages he will pretty much
> peg the CPU doing nothing.  Using a timer, you can get sufficient resolution
> and all the waiting is done in kernel mode leaving the CPU free for other
> things.
>
> I would also make a comment regarding the storage of the messages.  If you
> have a look at the Lidgren internals, it is already queuing the messages for
> you as the arrive so you don't want to double this effort.
>
> A lot of people are really tempted to use a lot of threads, one for reading
> and handling messages and others for processing etc. but I have written some
> pretty high performance servers (http://www.youtube.com/watch?v=kCp2-nfibzY) with

riki

unread,
Mar 10, 2011, 1:23:37 PM3/10/11
to lidgren-network
Matthew,

If it works don't break it. Meaning if your solution works for you no
need to change it!
All I was saying is that for high perf servers you must think about
many different things you normally don't have to .

The Borg Server is an evolution of +7 years of work and research,
based on other closed source projects. We tested so many different
approaches and designs and tried out even more that I cant count them.
Be assured that all those ideas (timer approach, one huge loop, no
queueing, single thread for send/receive) where thoroughly
investigated and tested.

Regarding the frame rate, well there are books written about this
topic but accidentally I am the author of the TXna Game Engine and
Titanlicht Game Engine. So I like to think about myself to understand
(to a certain degree) the insides of a game loop.
First there is no server sided game loop, but that's arguable.
Next you absolutely cant control the FPS with a timer! The Windows
timer has 54 ms resolution so the worst case error after 10 frames is
540 ms or half a second!!!!
If you take this road please use at least the stopwatch instead the
windows timer.

I have written an article, its in our web site archive...this is very
much outdated (maybe 6-7 years old) but its a still a valid
introduction into this topic: http://www.titanium.hr/Irrlicht/Tutorials/GameLoop/Tutorial.htm
The article is Irrlicht and physics related but explains pretty much
all the problems you will encounter with a Timer.

Again, if its really just a chat server with 10 clients any approach
works...but even a chat server can get in trouble if you suddenly have
100 eager clients connected.

Matthew Overall

unread,
Mar 10, 2011, 1:29:05 PM3/10/11
to lidgren...@googlegroups.com
Excellent suggestions Riki and Chris, thanks for your input!

I stand corrected regarding the use of the .Net Timers class being used in a primary game loop, though it makes it easy to set a fixed interval apparently they are not very accurate for Game Animation. Have a look at this, http://www.nuclex.org/articles/3-basics/5-how-a-game-loop-works it gives a great example of how to setup a time-stepped game loop without the use of timers. 

Matthew Overall

unread,
Mar 10, 2011, 1:38:55 PM3/10/11
to lidgren...@googlegroups.com
Looks like we were writing at the same time :o) 

Like I stated in my 2nd post, this is something I have not tried before. 

Chris Cowherd

unread,
Mar 10, 2011, 6:07:20 PM3/10/11
to lidgren...@googlegroups.com, Matthew Overall
No problem Matthew.  It's too bad everyone has to start measuring dicks on simple questions.  :)

Christopher Meek

unread,
Mar 14, 2011, 6:09:53 AM3/14/11
to lidgren-network
Wow, thanks every one, I certainly have a lot of things to go away and
try! I'll certainly take a look at the borg server riki so thanks for
that. When it comes to game loops I'm fairly experienced (having
previously work on PS2 titles) but never network gaming before.

I'll be sure to feed back how it all goes.

On Mar 10, 11:07 pm, Chris Cowherd <mad...@gmail.com> wrote:
> No problem Matthew.  It's too bad everyone has to start measuring dicks on
> simple questions.  :)
>
> On Thu, Mar 10, 2011 at 10:38 AM, Matthew Overall <matthew.over...@gmail.com
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages