|
===========================================
EDIT: I would like to mention i am new to programming forums, i screwed this one up as i was frustrated, and really didn't have a direct question. I hope i can improve my manners in the future.
Sorry MCM
===========================================
So let me start out with i am new to C# but not to programming in general. Mostly PHP background.
That being said, i am currently designing "Client", "Server" application. The server reads the COM port for a string, parse's it, inserts it into the database, then sends the client the id of the database entry over Asynchronous TCP. This happens randomly there is no rhyme or reason for when the Serial stream is received.
That being said, it is very important that the TCP transfer of the id is not being delayed at all, seconds really count in this application.
The problem I am having is users are logging off their computer and "Force Closing" the client before it has a chance to send the disconnect command to the server. When this happens the client cannot reconnect until i reset the server's client list.
I would like to implement a "Heartbeat" command, lets say server sends ping to a number of clients (currently three for QA, eventually between 50-100 clients) and the client returns pong meaning the connection is alive. If the client fails to respond within the limit (say 30 seconds to a minute) i would like to remove it from the client list.
But once again this cannot interrupt the main function of this software which is sending the id to the clients and would have to run as a background thread.
I am not familiar enough with background threads (or threads in general really) to make this happen, and after a week of reading and research i am still unsure of my ability to do such a thing within a reasonable amount of time.
I seek help in this matter, if anyone could direct me to a good article, or give me a snippet to start with i would greatly appreciate it.
This section of code is based heavily upon the following article:
A Chat Application Using Asynchronous TCP Sockets[^]
This is probably the reason for me not understanding this as well as i should, i cheated and manipulated this code to do what i needed. I didn't see the need to reinvent the wheel to send a couple digits over TCP, a few times a day.
Let me also note that this "Server Code" runs as a windows service on a server, the client is a Windows Form application.
In the Following Code the sendHeartBeat() method and command.Heartbeat have not actually been implemented, they are the start of my code for it.
Also i have removed the logging code for ease of reading, as my logging methods are a little robust but work well for my needs.
the server side TCP Class code is as follows:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace mgMapsServer.Classes
{
enum Command
{
Login,
Logout,
callLog,
heartbeat,
Reset,
Null
}
public class TCPConnector
{
struct ClientInfo
{
public Socket socket;
public string strName;
}
struct HBInfo
{
public Socket socket;
public int index;
}
ArrayList clientList;
Socket serverSocket;
ArrayList HeartbeatList;
byte[] byteData = new byte[1024];
public TCPConnector()
{
clientList = new ArrayList();
HeartbeatList = new ArrayList();
try
{
serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, Convert.ToInt32(Library.sqlVars("serverPort")));
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(4);
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
\*Logging Code*\
}
catch (Exception ex) { \*Logging Code*\ }
}
}
private void OnAccept(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
clientSocket.BeginReceive(byteData, 0,
byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), clientSocket);
}
catch (Exception ex) { \*Logging Code*\ }
}
private void OnReceive(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);
Data msgReceived = new Data(byteData);
Data msgToSend = new Data();
msgToSend.cmdCommand = msgReceived.cmdCommand;
msgToSend.strName = msgReceived.strName;
switch (msgReceived.cmdCommand)
{
case Command.heartbeat:
break;
case Command.Reset:
\*Logging Code*\
int rIndex = 0;
foreach (ClientInfo client in clientList)
{
clientList.RemoveAt(rIndex);
++rIndex;
}
break;
case Command.Login:
ClientInfo clientInfo = new ClientInfo();
clientInfo.socket = clientSocket;
clientInfo.strName = msgReceived.strName;
clientList.Add(clientInfo);
msgToSend.strMessage = "<<<" + msgReceived.strName + " has Connected to the Server>>>";
break;
case Command.Logout:
int nIndex = 0;
foreach (ClientInfo client in clientList)
{
if (client.socket == clientSocket)
{
clientList.RemoveAt(nIndex);
break;
}
++nIndex;
}
clientSocket.Close();
msgToSend.strMessage = "<<<" + msgReceived.strName + " has Disconnected from the server>>>";
break;
}
if ((msgReceived.cmdCommand != Command.heartbeat) || (msgReceived.cmdCommand != Command.heartbeat))
{
\*Logging Code*\
}
if (msgReceived.cmdCommand != Command.Logout) { clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket); }
}
catch (Exception ex) { \*Logging Code*\ }
}
public string callLogIDSender
{
get { return null; }
set { SendcallLogID(value); }
}
public void SendcallLogID(string ID)
{
try
{
Data msgToSend = new Data();
byte[] message;
msgToSend.cmdCommand = Command.callLog;
msgToSend.strMessage = ID;
message = msgToSend.ToByte();
\*Logging Code*\
foreach (ClientInfo clientInfo in clientList)
{
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
}
}
catch (Exception ex) { \*Logging Code*\ }
}
public void sendHeartBeat()
{
try
{
Data msgToSend = new Data();
byte[] message;
msgToSend.cmdCommand = Command.heartbeat;
msgToSend.strMessage = null;
message = msgToSend.ToByte();
int nIndex = 0;
foreach (ClientInfo clientInfo in clientList)
{
HBInfo tempHB = new HBInfo();
tempHB.index = nIndex;
tempHB.socket = clientInfo.socket;
HeartbeatList.Add(tempHB);
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
++nIndex;
}
}
catch (Exception e) { \*Logging Code*\ }
}
public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
\\Logging Code
}
}
}
class Data
{
public Data()
{
this.cmdCommand = Command.Null;
this.strMessage = null;
this.strName = null;
}
public Data(byte[] data)
{
this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);
int nameLen = BitConverter.ToInt32(data, 4);
int msgLen = BitConverter.ToInt32(data, 8);
if (nameLen > 0)
this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
else
this.strName = null;
if (msgLen > 0)
this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
else
this.strMessage = null;
}
public byte[] ToByte()
{
List<byte> result = new List<byte>();
result.AddRange(BitConverter.GetBytes((int)cmdCommand));
if (strName != null)
result.AddRange(BitConverter.GetBytes(strName.Length));
else
result.AddRange(BitConverter.GetBytes(0));
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(strMessage.Length));
else
result.AddRange(BitConverter.GetBytes(0));
if (strName != null)
result.AddRange(Encoding.UTF8.GetBytes(strName));
if (strMessage != null)
result.AddRange(Encoding.UTF8.GetBytes(strMessage));
return result.ToArray();
}
public string strName;
public string strMessage;
public Command cmdCommand;
}
modified 31-May-15 3:31am.
|
|
|
|
|
Member 11700380 wrote: That being said, it is very important that the TCP transfer of the id is not
being delayed at all, seconds really count in this application. If that is truly important, than you cannot work with Windows; the OS decides which application gets resources.
"As fast as possible" is something different, that one can do.
Do take not that a backgroundworker usually has a lower priority then the overall process. Since sending an ID should not stop the server from reading its comport, that would be a good idea.
I've seen the start of the code, but not a specific question. Do you have a list of active users that you can check if the heartbeat returns? How do you identify who's heartbeat is coming back (assuming multiple clients)?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
When the Client sends data to the server, the computer name is encoded with the message. This is how i distinguish between machines.
Also, "as fast as possible" will have to do. I was very frustrated the other night when i wrote the original post.
Specific Question: I need some Good research material on a background threading, I have read everything i could find over the past week, and still feel i am coming up short on fully understanding implementing threads safely and properly.
I have a working prototype running in a sandbox currently, I just keep reading about how difficult thread problems are to diagnose, and am afraid to implement them into my code, work on it for a few weeks, then come to find out i broke my code by threading incorrectly.
I think i am just to the point where i need to trust my code, and go for it.
|
|
|
|
|
Do you have any locking where the thread accesses shared resources or an invoke-pattern to return the results?
How about you post your new code?
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I have implemented a more in depth logging of the "TCP log in" process on both the client and the server side, i am going to give it a couple of days, to give my QA a chance to experience the errors i have been receiving from forced closes and attempts to reconnect and revisit this problem.
i feel i am making a mountain out of a mole hill...
I will reply to this post when i have some information that i fell will help me move forward with this problem, which hopefully will help someone in the future.
Also the server side code in question that i am running in my sandbox was included in the original post, listed under "heartbeat" in both the received data and its own method. All i did was place it in a separate application that user input is simulated using a database of user entries. So far so good, but i feel i am missing something far more simple than the problem i am trying to fix maybe i can figure a way to avoid the heartbeat all together...
As I said, i am going to give it a few days and review the logs to see what is "Really" going on.
|
|
|
|
|
In mvc asp.net controls are not working. Is it my error or we can't use it with mvc?
|
|
|
|
|
ASP.Net controls makes use of ViewState and PostBack. These work along side the standard event handling concepts used in web forms based applications. MVC, on the other hand, makes use of Controller which is responsible for handling handling user actions.
|
|
|
|
|
It's just a different technology based on a different framework, it's like asking "Why can't I use Spanish in Russia?"
If you want to use webform controls then use a webforms project. If you want to use mvc you'll need to the Html helper classes to do basic things like textboxes, checkboxes, dropdowns etc, and for more advanced things like "webgrid" etc there are some off-the-shelf mvc plug-ins you can use, or you'll just need to get familiar with html\http and implement it all yourself.
|
|
|
|
|
in one word Viewstate
you can still use to controls on an asp.net (not razor version)
MVC does give you the advantage of super light postbacks and responses but has. Where in mvc your information is being contained in the model (which obviously excludes ajax calls creates)
But in my personal opinion asp.net does seem to take more of an object oriented approach to reusing controls , which makes developing massive information system a lot less painful and quicker ; but the tradeoff is a lot of information being parsed back and forth that you are most likely not going to use every time a button is clicked which is bad for high traffic sites.
Chona1171
Web Developer (C#), Silverlight
|
|
|
|
|
The first thing I have done on any webforms site I've built in the last 15 years is to disable viewstate globally so that it has to be explicitly enabled on any controls that need it. People keep bringing up viewstate as if it is a decisive issue, completely ignoring the fact that it can easily be turned off. People who go to MVC because of "viewstate" are simply bad webforms programmers and they will go on to be bad MVC programmers.
Not a dig at you personally, it just gets my goat when people talk about viewstate as if it was some insurmountable evil.
|
|
|
|
|
Hi
I agree with you completely , what I normally do is put my viewstate in a session to avoid the big back and forth , and if you read my posts you'll find that they are completely pro ASP.Net over MVC
All I am saying is if you are hell bend on squeezing the very last bit of performance out of your app MVC would be the way to go (it would take you way longer to code and you'll most likely get lazy debugging front end code and just start implementing bad practices) but I still prefer ASP.NET using N-Tier Architecture and good practices over MVC any day
Chona1171
Web Developer (C#), Silverlight
|
|
|
|
|
What does the error - "Source is not available at current location" - means while using ajax controls?
|
|
|
|
|
This happens when the code you are trying to view does not exist in your project. Here[^] is a CP question answered that can help you.
|
|
|
|
|
I suppose have got wavecome M1206B modem device connected to the computer is complete and I have got the information fields (FULLNAME, BIRTHDAY, IDIDENTIFY, ISSUER, DATERANGE, PHONENUMBER, SERIAL) must register for the SIM card, ask syntax register using AT commands in HyperTerminal set of winxp ? after then switch AT Commands above as by as syntax of source code C# ?
|
|
|
|
|
Have you considered asking that in English, instead of just using as few words as possible?
It might help us to understand what the heck you are going on about...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
I suppose have got wavecome M1206B modem device connected to the computer is complete, if get the phone number SIM Imel successfully returned number SIM Imel, Status and the error Flag ?
|
|
|
|
|
Have you considered asking that in English, instead of just using as few words as possible?
It might help us to understand what the heck you are going on about...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Hi for All
I need method convert to bool[] from
1- string[]
for example string[] w;
i need convert w[0] to bool[]
2- byte
for example byte b;
i need convert byte to bool[]
======================================
also how can convert bool[] to byte
thank you for my support
|
|
|
|
|
You can make use of bool.Parse , bool.TryParse or Convert.ToBoolean to do so provided data in these arrays can be converted to boolean .
You will need to loop through each item in array to do so.
|
|
|
|
|
Hi,
thank you sir
sir can be give me example
Regards
|
|
|
|
|
Hi Sir
Sir how can write code to change w[0] to Boolean
w[0]=0xAA;
mean w[0]=10101010;
i need change w[0] to Boolean value mean {true false true false true false true false}
also this
byte kk=0xAA;
mean kk=10101010;
i need change kk to Boolean value mean true false true false true false true false
Regards
modified 29-May-15 1:53am.
|
|
|
|
|
The below statement if (bool.TryParse(var[i], out v))---> says you whether it's really converting/not.if it returns true,then converting else returns false.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string[] var = {"abc","bcd","cde"};
public bool call(string[] var)
{
int i;
bool v;
for (i=0;i<var.Length;i++)
{
if (bool.TryParse(var[i], out v))
return v;
else
return v;
}
return true;
}
private void Form1_Load(object sender, EventArgs e)
{
bool b = call(var);
}
}
Remember it's not possible to convert string/string[] to bool.If tries it threw an exception of type 'System.FormatException',may not terminate the program but threw an exception.
|
|
|
|
|
Hello friends,
I am saving multiple Workitems of type Task but while saving it throws an exception "There is a problem on the server. Contact your Team Foundation Server administrator.
InnerException {"TF400732: The request has been canceled."} System.Exception {System.Web.Services.Protocols.SoapException}
why I am facing this issue? please help me to resolve this.
Thanks
Manoj Kumar
|
|
|
|
|
You given us nothing to work with except for the most generic error message TFS can throw.
Only you know the circumstances under which the problem occurs and there are a ton of possible causes, so start researching what everyone else has run into[^].
|
|
|
|
|
Thanks sir for your reply. Even I know its most generic error. my code is simple like
WorkItemType workItemType = teamProject.WorkItemTypes["Task"];
for(int i=0;i<100;i++)
{
WorkItem task = new WorkItem(workItemType);
task.Fields["somefield"].Value = "somevalue";
task.save();
}
exception comes at task.save. and value of I varies some times 2, some times 4 even some times it reaches 60.
|
|
|
|
|