In Server/Client Applications, is it a memory consumption to use a timer that checks for each client if it is connected or not?
For example a Socket Server accepts a Socket Client and add it to a List, then a timer that checks each Client in the List via a loop, if it is not connected then removed from the List<> and fire an event... however though this way sounds hard especially that the timer's interval is 1 second... plus if there let's say 1000 client Connected, can the timer checks them all in 1 second? or should i make it bigger?
I care about the memory used by my app, and the timer capability of checking many clients in 1 sec. is that a true way? thanks in advanced.
No it's not a good idea because it already implements such a mechanism, the Timeout in both send operations and receive operations, meaning that if you set a receive timeout for 10 sec, call the Receive and nothing comes, it will already throw a exception, notifying you as you want to do with the timer...
The last time i created a server/client app like the one you are describing, i created a new thread with priority set a BelowNormal.
The only thing with Timers is that they (potentially) execute inside the UI thread meaning your form will become unresponsive or laggy.
Then i basically looped the thread continuously inside a Do/While loop until the application closed. Throw in a quick Threading.Thread.Sleep(100) and performance will be perfect.
Inside the loop, i'd check for incoming connection requests and like you say, add them to a list etc. You can then also handle communications with each connected client too as it'll have minimal impact.
Private Sub StartSocketsServer()
Try
Dim oThread As New Threading.Thread(AddressOf StartSocketsServer_Threaded)
With oThread
.Name = "Socket Server"
.Priority = Threading.ThreadPriority.BelowNormal
.IsBackground = True
.Start()
End With
Catch ex As Exception
'Handle exception
End Try
End Sub
Private Sub StartSocketsServer_Threaded()
Try
Do
'Perform all of your sockets here in a threaded environment.
Threading.Thread.Sleep(1000) '1 sec
Loop Until Me.IsDisposed
Catch ex As Exception
'Handle thread safe exceptions here
End Try
End Sub
Related
I am working on an assignment in asp.net to send notification email to users at specific intervals.
But the problem is that since the server is not privately owned i cannot implement a windows service on it.
Any ideas?
There's no reliable way to achieve that. If you cannot install a Windows Service on the host you could write a endpoint (.aspx or .ashx) that will send the email and then purchase on some other site a service which will ping this endpoint at regular intervals by sending it HTTP request. Obviously you should configure this endpoint to be accessible only from the IP address of the provider you purchase the service from, otherwise anyone could send an HTTP request to the endpoint and trigger the process which is probably undesirable.
Further reading: The Dangers of Implementing Recurring Background Tasks In ASP.NET.
There are several ways to get code executing on an interval that don't require a windows service.
One option is to use the Cache class - use one of the Insert overloads that takes a CacheItemRemovedCallback - this will be called when the cache item is removed. You can re-add the cache item with this callback again and again...
Though, the first thing you need to do is contact the hosting company and find out if they already have some sort of solution for you.
You could set up a scheduled task on the server to invoke a program with the desired action.
You can always use a System.Timer and create a call at specific intervals. What you need to be careful is that this must be run one time, eg on application start, but if you have more than one pools, then it may run more times, and you also need to access some database to read the data of your actions.
using System.Timers;
var oTimer = new Timer();
oTimer.Interval = 30000; // 30 second
oTimer.Elapsed += new ElapsedEventHandler(MyThreadFun);
oTimer.Start();
private static void MyThreadFun(object sender, ElapsedEventArgs e)
{
// inside here you read your query from the database
// get the next email that must be send,
// you send them, and mark them as send, log the errors and done.
}
why I select system timer:
http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
more words
I use this in a more complex class and its work fine. What are the points that I have also made.
Signaling the application stop, to wait for the timer to end.
Use mutex and database for synchronize the works.
Easiest solution is to exploit global.asax application events
On application startup event, create a thread (or task) into a static singleton variable in the global class.
The thread/task/workitem will have an endless loop while(true) {...} with your "service like" code inside.
You'll also want to put a Thread.Sleep(60000) in the loop so it doesn't eat unnecessary CPU cycles.
static void FakeService(object obj) {
while(true) {
try {
// - get a list of users to send emails to
// - check the current time and compare it to the interval to send a new email
// - send emails
// - update the last_email_sent time for the users
} catch (Exception ex) {
// - log any exceptions
// - choose to keep the loop (fake service) running or end it (return)
}
Thread.Sleep(60000); //run the code in this loop every ~60 seconds
}
}
EDIT Because your task is more or less a simple timer job any of the ACID type concerns from an app pool reset or other error don't really apply, because it can just start up again and keep trucking along with any data corruption. But you could also use the thread to simply execute a request to an aspx or ashx that would hold your logic.
new WebClient().DownloadString("http://localhost/EmailJob.aspx");
I've been asked to write a method that will allow a caller to send a command string to a hardware device via the serial port. After sending the command the method must wait for a response from the device, which it then returns to the caller.
To complicate things the hardware device periodically sends unsolicited packets of data to the PC (data that the app must store for reporting). So when I send a serial command, I may receive one or more data packets before receiving the command response.
Other considerations: there may be multiple clients sending serial commands potentially at the same time as this method will form the basis of a WCF service. Also, the method needs to be synchronous (for reasons I won't go into here), so that rules out using a callback to return the response to the client.
Regarding the "multiple clients", I was planning to use a BlockingCollection<> to queue the incoming commands, with a background thread that executes the tasks one at a time, thus avoiding serial port contention.
However I'm not sure how to deal with the incoming serial data. My initial thoughts were to have another background thread that continually reads the serial port, storing data analysis packets, but also looking for command responses. When one is received the thread would somehow return the response data to the method that originally sent the serial command (which has been waiting ever since doing so - remember I have a stipulation that the method is synchronous).
It's this last bit I'm unsure of - how can I get my method to wait until the background thread has received the command's response? And how can I pass the response from the background thread to my waiting method, so it can return it to the caller? I'm new to threading so am I going about this the wrong way?
Thanks in advance
Andy
First of all: When you use the SerialPort class that comes with the framework, the data received event is asynchronous already. When you send something, data is coming in asynchronously.
What I'd try is: queue all requests that need to wait for an answer. In the overall receive handler, check whether the incoming data is the answer for one of the requests. If so, store the reply along with the request information (create some kind of state class for that). All other incoming data is handled normally.
So, how to make the requests wait for an answer? The call that is to send the command and return the reply would create the state object, queue it and also monitor the object to see whether an answer was received. If an answer was received, the call returns the result.
A possible outline could be:
string SendAndWait(string command)
{
StateObject state = new StateObject(command);
state.ReplyReceived = new ManualResetEvent(false);
try
{
SerialPortHandler.Instance.SendRequest(command, state);
state.ReplyReceived.WaitOne();
}
finally
{
state.ReplyReceived.Close();
}
return state.Reply;
}
What's SerialPortHandler? I'd make this a singleton class which contains an Instance property to access the singleton instance. This class does all the serial port stuff. It should also contain an event that is raised when "out of band" information comes in (data that is not a reply to a command).
It also contains the SendRequest method which sends the command to the serial device, stores the state object in an internal list, waits for the command's reply to come in and updates the state object with the reply.
The state object contains a wait handle called ReplyReceived which is set by the SerialPortHandler after it has changed the state object's Reply property. That way you don't need a loop and Thread.Sleep. Also, instead of calling WaitOne() you could call WaitOne(timeout) with timeout being a number of milliseconds to wait for the reply to come in. This way you could implement some kind of timeout-feature.
This is how it could look in SerialPortHandler:
void HandlePossibleCommandReply(string reply)
{
StateObject state = FindStateObjectForReply(reply);
if (state != null)
{
state.Reply = reply;
state.ReplyReceived.Set();
m_internalStateList.Remove(state);
}
}
Please note: This is what I'd try to start with. I'm sure this can be very much optimized, but as you see there's not much "multithreading" involved where - only the SendAndWait method should be called in a way so that multiple clients can issue commands while another client is still waiting for its response.
EDIT
Another note: You're saying that the method should form the basis for a WCF service. This makes things easier, as if you configure the service right, a instance of the service class will be created for every call to the service, so the SendAndWait method would "live" in its own instance of the service and doesn't even need to be re-entrant at all. In that case, you just need to make sure that the SerialPortHandler is always active (=> is created and running independently from the actual WCF service), no matter whether there's currently an instance of your service class at all.
EDIT 2
I changed my sample code to not loop and sleep as suggested in the comments.
If you really want to block until the background thread has received your command response, you could look into having the background thread lock an object when you enqueue your command and return that to you. Next, you wait for the lock and continue:
// in main code:
var locker = mySerialManager.Enquee(command);
lock (locker)
{
// this will only be executed, when mySerialManager unlocks the lock
}
// in SerialManager
public object Enqueue(object command)
{
var locker = new Object();
Monitor.Enter(locker);
// NOTE: Monitor.Exit() gets called when command result
// arrives on serial port
EnqueueCommand(command, locker);
return locker;
}
A couple things. You need to be able to tie up serial responses to the commands that requested them. I assume that there's some index or sequence number that goes out with the command and comes back in the response?
Given that, you should be OK. You need some sort of 'serialAPU' class to represent the request and response. I don't know what these are, maybe just strings, I don't know. The class should have an autoResetEvent as well. Anyway, in your 'DoSerialProtocol()' function, create a serialAPU, load it up with request data, queue it off to the serial thread and wait on the autoResetEvent. When the thread gets the serialAPU, it can store an index/sequence number in the serialAPU, store the serialAPU in a vector and send off the request.
When data comes in, do you protocol stuff and, if the data is a valid response, get the index/sequence from the data and look up the matching value in the serialAPU's in the vector. Remove the matching serialAPU from the vector, load it up with the response data and signal the autoResetEvent. The thread that called 'DoSerialProtocol()' originally will then run on and can handle the response data.
There are lots of 'wiggles' of course. Timeouts is one. I would be tempted to have a state enum in the serialAPU, protected by a CritcalSection or atomicCompareandSwap, initialized ot 'Esubmitted'. If the oringinating thread times out its wait on the autoResetEvent, it tries to set the state enum in its serialAPU to 'EtimedOut'. If it succeeds, fine, it returns an error to the caller. Simlarly, in the serial thread, if it finds a serialAPU whose state is EtimedOut, it just removes it from the container. If it finds the serialAPU that matches response data, it tries to change the state to 'EdataRx' and if it succeeds. fires the autoRestEvent.
Another is the annoying OOB data. If that comes in, create a serialAPU, load in the OOB data, set the state to 'EOOBdata' and call some 'OOBevent' with it.
I would advise you to look at the BackgroundWorker-Class
Ther is a Event in this class (RunWorkerCompleted) which is fired when the worker has finished his job.
I'm programming simple TCP file transfer using TcpListener on reciever side and TcpClient on sender side. I have 2 options - synchronnous or asynchronnous. If I use synchronnous, I have to put sending/recieving methods into BackgroundWorker, to prevent freezing GUI thread. Asynchronnous version is without problems...
My question is, how to stop running file transfer?
In synchronnous version I tried to use BackgroundWorker.CancelAsync() method, and in every loop iteration check BackgroundWorker.CancellationPending property, but it doesn't seems to work (CancelAsync is probably not setting CancellationPending property) :(
In asynchronnous version I tried to use volatile variable Indicator and in every Callback check its value. Problem is, when I change its value in Stop() method, and than I check it in Callback, callback still reads its previous value :(
CancelASync should work; did you set:
backgroundWorker.WorkerSupportsCancellation = true:
Are you saying that you aren't reading the correct "cancel state" when you check it? This suggests you're not synchronising the flag between your threads correctly.
Or is it just that you won't ever check for the "cancel state" unless you receive some new data? (From the way you describe your tx/rx "loops", in both sync and async cases you will have to receive a new datagram before you will get a chance to check the 'cancel' flag)
If you are in control of both ends of the data transfer, then whichever end (client or server) wishes to abort should ideally send a special datagram to the other end to stop the transfer - otherwise the other end will attempt to continue sending/receiving, not knowing that it's on its own. So perhaps a better approach would be to actually send/receive a "cancel transfer" datagram, which would inform the TCP code at both ends that you wish to cancel. (i.e. you wouldn't need to have a special cancel flag, you would simply check if the datagram you are about to send or have just received is a "cancel transfer" datagram). This would allow both ends to gracefully and cleanly close down.
My original question from a while ago is MSMQ Slow Queue Reading, however I have advanced from that and now think I know the problem a bit more clearer.
My code (well actually part of an open source library I am using) looks like this:
queue.Receive(TimeSpan.FromSeconds(10), MessageQueueTransactionType.Automatic);
Which is using the Messaging.MessageQueue.Receive function and queue is a MessageQueue. The problem is as follows.
The above line of code will be called with the specified timeout (10 seconds). The Receive(...) function is a blocking function, and is supposed to block until a message arrives in the queue at which time it will return. If no message is received before the timeout is hit, it will return at the timeout. If a message is in the queue when the function is called, it will return that message immediately.
However, what is happening is the Receive(...) function is being called, seeing that there is no message in the queue, and hence waiting for a new message to come in. When a new message comes in (before the timeout), it isn't detecting this new message and continues waiting. The timeout is eventually hit, at which point the code continues and calls Receive(...) again, where it picks up the message and processes it.
Now, this problem only occurs after a number of days/weeks. I can make it work normally again by deleting & recreating the queue. It happens on different computers, and different queues. So it seems like something is building up, until some point when it breaks the triggering/notification ability that the Receive(...) function uses.
I've checked a lot of different things, and everything seems normal & isn't different from a queue that is working normally. There is plenty of disk space (13gig free) and RAM (about 350MB free out of 1GB from what I can tell). I have checked registry entries which all appear the same as other queues, and the performance monitor doesn't show anything out of the normal. I have also run the TMQ tool and can't see anything noticably wrong from that.
I am using Windows XP on all the machines and they all have service pack 3 installed. I am not sending a large amount of messages to the queues, at most it would be 1 every 2 seconds but generally a lot less frequent than that. The messages are only small too and nowhere near the 4MB limit.
The only thing I have just noticed is the p0000001.mq and r0000067.mq files in C:\WINDOWS\system32\msmq\storage are both 4,096KB however they are that size on other computers also which are not currently experiencing the problem. The problem does not happen to every queue on the computer at once, as I can recreate 1 problem queue on the computer and the other queues still experience the problem.
I am not very experienced with MSMQ so if you post possible things to check can you please explain how to check them or where I can find more details on what you are talking about.
Currently the situation is:
ComputerA - 4 queues normal
ComputerB - 2 queues experiencing problem, 1 queue normal
ComputerC - 2 queues experiencing problem
ComputerD - 1 queue normal
ComputerE - 2 queues normal
So I have a large number of computers/queues to compare and test against.
Any particular reason you aren't using an event handler to listen to the queues? The System.Messaging library allows you to attach a handler to a queue instead of, if I understand what you are doing correctly, looping Receive every 10 seconds. Try something like this:
class MSMQListener
{
public void StartListening(string queuePath)
{
MessageQueue msQueue = new MessageQueue(queuePath);
msQueue.ReceiveCompleted += QueueMessageReceived;
msQueue.BeginReceive();
}
private void QueueMessageReceived(object source, ReceiveCompletedEventArgs args)
{
MessageQueue msQueue = (MessageQueue)source;
//once a message is received, stop receiving
Message msMessage = null;
msMessage = msQueue.EndReceive(args.AsyncResult);
//do something with the message
//begin receiving again
msQueue.BeginReceive();
}
}
We are also using NServiceBus and had a similar problem inside our network.
Basically, MSMQ is using UDP with two-phase commits. After a message is received, it has to be acknowledged. Until it is acknowledged, it cannot be received on the client side as the receive transaction hasn't been finalized.
This was caused by different things in different times for us:
once, this was due to the Distributed Transaction Coordinator unable to communicate between machines as firewall misconfiguration
another time, we were using cloned virtual machines without sysprep which made internal MSMQ ids non-unique and made it receive a message to one machine and ack to another. Eventually, MSMQ figures things out but it takes quite a while.
Try this
public Message Receive( TimeSpan timeout, Cursor cursor )
overloaded function.
To get a cursor for a MessageQueue, call the CreateCursor method for that queue.
A Cursor is used with such methods as Peek(TimeSpan, Cursor, PeekAction) and Receive(TimeSpan, Cursor) when you need to read messages that are not at the front of the queue. This includes reading messages synchronously or asynchronously. Cursors do not need to be used to read only the first message in a queue.
When reading messages within a transaction, Message Queuing does not roll back cursor movement if the transaction is aborted. For example, suppose there is a queue with two messages, A1 and A2. If you remove message A1 while in a transaction, Message Queuing moves the cursor to message A2. However, if the transaction is aborted for any reason, message A1 is inserted back into the queue but the cursor remains pointing at message A2.
To close the cursor, call Close.
If you want to use something completely synchronous and without event you can test this method
public object Receive(string path, int millisecondsTimeout)
{
var mq = new System.Messaging.MessageQueue(path);
var asyncResult = mq.BeginReceive();
var handles = new System.Threading.WaitHandle[] { asyncResult.AsyncWaitHandle };
var index = System.Threading.WaitHandle.WaitAny(handles, millisecondsTimeout);
if (index == 258) // Timeout
{
mq.Close();
return null;
}
var result = mq.EndReceive(asyncResult);
return result;
}
I'm working on a C# Server application for a game engine I'm writing in ActionScript 3. I'm using an authoritative server model as to prevent cheating and ensure fair game. So far, everything works well:
When the client begins moving, it tells the server and starts rendering locally; the server, then, tells everyone else that client X has began moving, among with details so they can also begin rendering. When the client stops moving, it tells the server, which performs calculations based on the time the client began moving and the client render tick delay and replies to everyone, so they can update with the correct values.
The thing is, when I use the default 20ms tick delay on server calculations, when the client moves for a rather long distance, there's a noticeable tilt forward when it stops. If I increase slightly the delay to 22ms, on my local network everything runs very smoothly, but in other locations, the tilt is still there. After experimenting a little, I noticed that the extra delay needed is pretty much tied to the latency between client and server. I even boiled it down to a formula that would work quite nicely: delay = 20 + (latency / 10).
So, how would I proceed to obtain the latency between a certain client and the server (I'm using asynchronous sockets). The CPU effort can't be too much, as to not have the server run slowly. Also, is this really the best way, or is there a more efficient/easier way to do this?
Sorry that this isn't directly answering your question, but generally speaking you shouldn't rely too heavily on measuring latency because it can be quite variable. Not only that, you don't know if the ping time you measure is even symmetrical, which is important. There's no point applying 10ms of latency correction if it turns out that the ping time of 20ms is actually 19ms from server to client and 1ms from client to server. And latency in application terms is not the same as in networking terms - you may be able to ping a certain machine and get a response in 20ms but if you're contacting a server on that machine that only processes network input 50 times a second then your responses will be delayed by an extra 0 to 20ms, and this will vary rather unpredictably.
That's not to say latency measurement it doesn't have a place in smoothing predictions out, but it's not going to solve your problem, just clean it up a bit.
On the face of it, the problem here seems to be that that you're sent information in the first message which you use to extrapolate data from until the last message is received. If all else stays constant then the movement vector given in the first message multiplied by the time between the messages will give the server the correct end position that the client was in at roughly now-(latency/2). But if the latency changes at all, the time between the messages will grow or shrink. The client may know he's moved 10 units, but the server simulated him moving 9 or 11 units before being told to snap him back to 10 units.
The general solution to this is to not assume that latency will stay constant but to send periodic position updates, which allow the server to verify and correct the client's position. With just 2 messages as you have now, all the error is found and corrected after the 2nd message. With more messages, the error is spread over many more sample points allowing for smoother and less visible correction.
It can never be perfect though: all it takes is a lag spike in the last millisecond of movement and the server's representation will overshoot. You can't get around that if you're predicting future movement based on past events, as there's no real alternative to choosing either correct-but-late or incorrect-but-timely since information takes time to travel. (Blame Einstein.)
One thing to keep in mind when using ICMP based pings is that networking equipment will often give ICMP traffic lower priority than normal packets, especially when the packets cross network boundaries such as WAN links. This can lead to pings being dropped or showing higher latency than traffic is actually experiencing and lends itself to being an indicator of problems rather than a measurement tool.
The increasing use of Quality of Service (QoS) in networks only exacerbates this and as a consequence though ping still remains a useful tool, it needs to be understood that it may not be a true reflection of the network latency for non-ICMP based real traffic.
There is a good post at the Itrinegy blog How do you measure Latency (RTT) in a network these days? about this.
You could use the already available Ping Class. Should be preferred over writing your own IMHO.
Have a "ping" command, where you send a message from the server to the client, then time how long it takes to get a response. Barring CPU overload scenarios, it should be pretty reliable. To get the one-way trip time, just divide the time by 2.
We can measure the round-trip time using the Ping class of the .NET Framework.
Instantiate a Ping and subscribe to the PingCompleted event:
Ping pingSender = new Ping();
pingSender.PingCompleted += PingCompletedCallback;
Add code to configure and action the ping.
Our PingCompleted event handler (PingCompletedEventHandler) has a PingCompletedEventArgs argument. The PingCompletedEventArgs.Reply gets us a PingReply object. PingReply.RoundtripTime returns the round trip time (the "number of milliseconds taken to send an Internet Control Message Protocol (ICMP) echo request and receive the corresponding ICMP echo reply message"):
public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
...
Console.WriteLine($"Roundtrip Time: {e.Reply.RoundtripTime}");
...
}
Code-dump of a full working example, based on MSDN's example. I have modified it to write the RTT to the console:
public static void Main(string[] args)
{
string who = "www.google.com";
AutoResetEvent waiter = new AutoResetEvent(false);
Ping pingSender = new Ping();
// When the PingCompleted event is raised,
// the PingCompletedCallback method is called.
pingSender.PingCompleted += PingCompletedCallback;
// Create a buffer of 32 bytes of data to be transmitted.
string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] buffer = Encoding.ASCII.GetBytes(data);
// Wait 12 seconds for a reply.
int timeout = 12000;
// Set options for transmission:
// The data can go through 64 gateways or routers
// before it is destroyed, and the data packet
// cannot be fragmented.
PingOptions options = new PingOptions(64, true);
Console.WriteLine("Time to live: {0}", options.Ttl);
Console.WriteLine("Don't fragment: {0}", options.DontFragment);
// Send the ping asynchronously.
// Use the waiter as the user token.
// When the callback completes, it can wake up this thread.
pingSender.SendAsync(who, timeout, buffer, options, waiter);
// Prevent this example application from ending.
// A real application should do something useful
// when possible.
waiter.WaitOne();
Console.WriteLine("Ping example completed.");
}
public static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
// If the operation was canceled, display a message to the user.
if (e.Cancelled)
{
Console.WriteLine("Ping canceled.");
// Let the main thread resume.
// UserToken is the AutoResetEvent object that the main thread
// is waiting for.
((AutoResetEvent)e.UserState).Set();
}
// If an error occurred, display the exception to the user.
if (e.Error != null)
{
Console.WriteLine("Ping failed:");
Console.WriteLine(e.Error.ToString());
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
Console.WriteLine($"Roundtrip Time: {e.Reply.RoundtripTime}");
// Let the main thread resume.
((AutoResetEvent)e.UserState).Set();
}
You might want to perform several pings and then calculate an average, depending on your requirements of course.