Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
I'd like to have a server app that provides a messaging service between the clients. There a few different sort of things I'd like to do:
- When certain fields are updated on a certain BO, it changes the application state. Rather than code to errors (because another user attempts something that was legal when it retrieved the state, but the state has now changed), I'd like to be able to just notify the clients so they can get the new state and adjust to it.
- For administration purposes, it would be good to know who is on, in real time. The way chat clients can show a list of friends online is what got me thinking about doing something chat like (though I don't intend to allow users to chat, just the client apps).
- For both administration and security purposes, I'd like to be able to kick off users, send out notifications etc. in real time. This would be used when the app is being upgraded, to make sure no one is on (and give them a 10 min warning). For security, in case we have a particularly naughty user, I could kick them off immediately.
I'm just a total newbie at doing anything like this. I've done a bit of research on using network streams, but don't know where to start. I'm also wondering how I'd do this if I were to use IIS and an ASPX page. I'm not sure that would work because I'd need to have a client talk to the server, which would broadcast to other clients.
Any help/starting tips would greatly appreciated!
Thanks!
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
Well, the data being passed back and forth would depend on how you create your request and response objects. You could create a string with pipe delimmiters and then parse it on either side. Or, you could use a BinaryWriter and BinaryRead to write the data to a byte array (kindof creating your own serialization) and then put it back to gether on the other side. In either case, you could use a network stream to read and write to and from. Probably the best way to go would be to use a BinaryFormater (serialization) to serialize the data and then pass it back and forth as a stream (BinaryRead, BinaryWriter). If you do this, it would be the cleanest and easiest to expand as you move forward and add more and more logic to this server and client.
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Thanks Trent. I think that gives me enough info to get started!  Have a great Christmas!
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
You are welcome Greg, and please keep us informed with your progress in this project. Trent, is the Server Service using a database to hold the status information or you are using an xml file? Also I assume you can use SF to create the Server Console application, right?
Edhy Rijo
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
Trent, is the Server Service using a database to hold the status information or you are using an xml file? Neither. An internal collection with custom items. If the service shuts down, the clients will bail out. You don't want to store this type of information in any type of database. If you do, then you will always fight sync and update problems. What if the server dies, etc. So this should all be real-time. Also I assume you can use SF to create the Server Console application, right?
Yup...we did
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Hi Greg, I am about to start a new SF project to handle the Server service features. Did yo review any of the TCP libraries here that deals with communication between clients and server? If you have any opnion you can share I will really appreciate since I have to have this done in a week or so. Thanks!
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
I did some research/test projects on this, but got derailed. However, here is what my current thinking is: - .NET has all you need to handle the network communication. A TCPListener/TCPClient I believe. That part seems pretty darned easy. - Threading will be key, so if you aren't up to speed on threading (asynch especially), read up on that. - Serialization is also key to how you pass data back and forth. You'd likely just use the binary serializer, but I didn't get that far to know. - You need to know how to make a Service. Not rocket science and was pretty straight forward. I am using a book (which was pretty marginal, but I still learned the basics). Not sure I'd recommend it, but it is working for me. http://www.amazon.com/Programming-Windows-Services-Microsoft-Visual/dp/073562433X/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1233971392&sr=8-1This is of course just the underlying plumbing that allows the client to talk to the server. You'll need the class(s) that would actually manage the business rules. I think what trent was talking about is creating a class, especially within the client, that makes it very easy to handle the communication. This class would wrap the code that actually uses the TCPClient, bundles up any data, sends message and processes result. Not much, but that's all I got so far...keep us updated!
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Greg McGuffey (02/06/2009) Not much, but that's all I got so far...keep us updated! Hi Greg, Sorry for the delayed reply. Thanks for the info, you are right about .NET having all the tools needed to handle the communications, but sometimes 3rd party libraries will offer easier and faster approach to the solution. Also thanks for the book recommendation, I will get it, since I have a lot to learn about Windows Services, I have done some work with Services with my VFP applications in the past, but for what I have read with VB.NET is much more easier since there is a special project to create a Service application. I will keep up posted on my findings. The more I think about this, the bigger this whole Windows Server/Console Application will be in order to manage a commercial application license and connections.
Edhy Rijo
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Greg McGuffey (02/06/2009) ...You need to know how to make a Service. Not rocket science and was pretty straight forward. I am using a book (which was pretty marginal, but I still learned the basics). Not sure I'd recommend it, but it is working for me.Greg, Just want to thank you on the recommendation of this book "Programming Windows Services with MS VB 2008" so far it has been pretty good to me in getting started with all the understanding about Windows Services. Oh, btw, I got it new from Hightech Computer at amazon.com for $13.99 includind shipping charges.
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Sweet!  It's not a great book. Lots of omission and typos. But it did help me a lot understanding how to do a service! Glad your project is moving right along! I'm jealous. I've been pulled in yet another direction for the time being
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Trent, I have a question about the Service and Server Console applications. I am doing the following, in the Service application I have a BO which will hold the list of all connected workstations and this BO will be updated OnConnect and OnDisconnect to add/remove the records, now in the Server Console application I have a list view in which I want to show the data in the Service BO, I am still not clear how to accomplish this, but here are some ideas: - The Server Console will also connect to the Service application with a different parameter to let it know that it is the Server Console and the service will pass a serialized BO to the Server Console to show the connected clients in the listview. Still I don't know how to do the serialization process but guess it should not be hard.
- The Server Console can create an XML file with the connected clients and the Server Console can read this file, etc. This approach could be more difficult to handle since I will need to have this XML file in an specific folder and also would need a timer to keep reading from each and it would be a lot of IO traffic.
- From the Service application I could create an Instance of the Server Console application, but that would be also a bit complicated.
So, from all 3 above I would go with option 1, but before I continue further could you or somebody else comment on this or any other recommendation to handle this? Thanks!
Edhy Rijo
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
Yeah, based on your options there 1 would be best. How you set this up will be very important in regards to scalability and growth within your application because it won't be long before you need to add some new functionality. You will want to have a "service port" that is exposed on your service application to which the server console will connect to administrate and retrieve all information. You can still use sockets on this, but for arguments sake, let assume that we will use port 20010 as the administration port on the service application. When the server console fires up, it will communicated with the service on that point to obtain information...but it should not "crash" if the service is down. In fact, if run on the same machine as the service, it should be able to start, stop, and restart he service from within the server console: 
This just makes it easier for the end-user as well...especially in service call type of scenarios. But through this port, you can do whatever you need...send serialized BOs back and forth, etc. In all actuallity, I would probably not send a serialized BO back and forth in this case, but rather create a query type of situation where I send a request and a response, not unlike web services. This way you can create a NetRequest class and a NetResponse class (or whatever you want to call them) that wrap this logic for you and know how to send and receive the NetStream data on both sides...so if you WANTED to send over a serialized BO you could. For populating a list with the connected users or something that would probably be fine. But these are just some ideas of how we designed our server service and console that might help.
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Trent,
How does the server console figure out the status of the service? Also, how do you start/stop/pause the server from the server console?
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
Using the ServiceController class. It makes it really easy! System.ServiceProcess.ServiceController
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Trent, Thanks for the info. Now back to serialization, I am trying to use the SerializeToByteArray but it is not working for me, I have the feeling my code is not correct, here is my approach: ' Serialize the BO into a ByteArray Dim pszOutByte As System.Byte()pszOutByte = Me.bizConnectedClients1.SerializeToByteArray
' DeSerialize the BO from a ByteArray Dim loBO As New bizConnectedClientsBusinessLayer.DeserializeBusinessObject(e.TextB) Me.BizConnectedClients1.CopyDataFrom(loBO, BusinessCloneDataType.ClearAndFillFromDefaultView)loBO.Dispose()
In above code e.TextB contain the serialized BO byte stream. When testing this I get the following error when trying to Deserialize the BO: SerializationException The input stream is not a valid binary format. The starting contents (in bytes) are: 34-31-36-32-32-34-36-33-0D-0A-54-65-73-74-20-4F-6E ... Source : System.Windows.Forms Stack Trace: at System.Windows.Forms.Control.EndInvoke(IAsyncResult asyncResult) at nsoftware.IPWorks.Ipport.nsoftware.core.IIpportEvents.FireDataIn(Byte[] text, Boolean EOL)
What is it that I am missing here?
Edhy Rijo
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
I am not sure what e.TextB is, but assuming it is the serizlized byte array, you are not placing the deserialized BO into a variable: loBo = BusinessLayer.DeserializeBusinessObject(e.TextB) And you will need to type is as well. So it would look more like this: Dim loBO As bizConnectedClients loBO = DirectCast(BusinessLayer.DeserializeBusinessObject(e.TextB), bizConnectedClients)
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Trent L. Taylor (03/11/2009) Using the ServiceController class. It makes it really easy!Cool! I'll check that out.
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Hi Trent/Greg, Just a note to say thanks again. So far I was able to create my version of a Server Console and a Server Service using the IP*Works library from www.nsoftware.com and the book for Windows Services suggested by Greg in this thread. This has been a great experience working outside of just the database process, using secured XML files managed by the SF Business Object to store the Server Settings information and using a ListView with all the goodies of the SF BO to show connected clients without saving any data to a database, this whole process shows once again the power in the SF framework. On a side note, I was having a lot of trouble with the IP*Works and sending the BO as a byte array, despite Trent's support replies I could not make it work to a satisfactory level, so I decided to simply use a predefined string which I then parsed and it worked just great. Thanks guys!
Edhy Rijo
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Awesome Edhy! I'm jonesing to work on a service like this myself...alas, no time at the moment.  I'll be referring back to this thread when I do though!
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Trent, One more question, for the client do you allow the end user to type in the IP address of the Server to connect to or is there a way for the client to discover the Server? In my case, I would like to keep the client locked down to the network segment they are installed on, this way a customer with different branches will not be able to connect to the Server Service from remote locations. Any suggestion on how to handle this logistic situation?
Edhy Rijo
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
One more question, for the client do you allow the end user to type in the IP address of the Server to connect to or is there a way for the client to discover the Server? We do allow it if the server cannot be automatically located. We use a UDP boradcast from the client if it cannot connect t the server. The server is listening on that UDP port and sends out a UDP broadcast of its location to which the client will retrieve the servers location and login. You can find a lot of samples on the internet about this. I did a quick serach and found some CodeProject samples. Here is a chart sample that uses a UDP broadcast. http://www.codeproject.com/KB/IP/socketsincs.aspx?fid=2956&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=1070795
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Hi Trent, I am trying to implement my version of Service Console to send the connection information to a SF application. In the AppMain.vb I need to communicate with the Service and get the connection, so far so good, I am doing this in the SetDataSources(), but if something is wrong and I need to close the application how do I do that? I tried something like:
System.Windows.Forms.Application.Exit()
Exit sub
But the flow of the StrataFrameApplication.RunApplication() continues instead of exiting. Any recommendation on how to stop the application if I don't get the connection string from my Service?
Edhy Rijo
|
|
|
Trent Taylor
|
|
Group: StrataFrame Developers
Posts: 6.6K,
Visits: 6.9K
|
In VB you can just call "End": End But the Exit should have worked. I use this at times to provide an exit code so I can tie into other applications (or shells ) and take logic if a certain exit code occurs.
|
|
|
Edhy Rijo
|
|
Group: StrataFrame Users
Posts: 2.4K,
Visits: 23K
|
Thanks Trent, "End" did the trick. I knew it should be something really simple
Edhy Rijo
|
|
|