Asked by:
Pattern for Reading a Persistent StreamSocket

Question
-
Greetings everyone. I am looking for the best way to implement the processing of events from a persistent socket connection. The application will have a persistent socket connection to a device. The communication is base on TCP and I am using a StreamSocket for this. The communication pattern is as follows:
[MyApp] -- Query Status --> [Device]
<-- Response ---
or
[MyApp] <---- Event ---- [Device] (Something changed on the device)
I have created a Model for the device that is bound to my View (a page). The model implements INotifyPropertyChanged so I expect the controls on the page to change when the properties of the model change.
The problem I have is processing the InputStream because it is persistent and the Device is designed to work this way.
I have looked at the examples such as:
http://code.msdn.microsoft.com/windowsapps/Creating-a-ThreadPool-work-9665cdff
The problem with this example is that it there is not concept of model and view. The worker thread is embedded in the view which would not be practical.
[it would be nice if the StreamSocket or DataReader had an event similar to the StreamSocketListener Connection event so that I didn't need to mess around with background threads and marshalling etc]
What I have done is in the model open a connection and start a worker thread to listen for events:
public async Task Connect(MainPage MainPage) { _page = MainPage; HostName serverHostName = new HostName("xxx.xxx.x.x"); string port = "60128"; try { if (_clientSocket != null) { _clientSocket.Dispose(); } _clientSocket = new StreamSocket(); _clientSocket.Control.NoDelay = true; //connect to the device await _clientSocket.ConnectAsync(serverHostName, port); //start the listener thread for reading data on the stream await Task.Factory.StartNew(ReadDeviceEvents); } catch (Exception ex) { } }
private async void ReadDeviceEvents() { if (_clientSocket != null) { try { DataReader reader = new DataReader(_clientSocket.InputStream); while (true) { string c = string.Empty; //read the eISCP Header uint sizeFieldCount = await reader.LoadAsync(16); string sheader = reader.ReadString(16); ISCPHeader header = new ISCPHeader(sheader); //read the data uint dataSize = await reader.LoadAsync(header.DataSize); string data = reader.ReadString(dataSize); ISCPResponse response = new ISCPResponse(header, data); ProcessEvent(response); } } catch (Exception ex) { #if DEBUG System.Diagnostics.Debug.WriteLine("ISCPController.ReadDeviceEvents() - Read Error: " + ex.Message); #endif } } }
private void ProcessEvent(ISCPResponse response) { System.Diagnostics.Debug.WriteLine(string.Format("Event Received CMD {0} PARM {1}", response.Command, response.Parameter)); bool powerOn = false; if (response.Command.Equals("PWR")) { if (response.Parameter.Equals("01")) { powerOn = true; } Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( CoreDispatcherPriority.High, new DispatchedHandler(() => { IsPowerOn = powerOn; //***** I was hoping this would trigger the bindings in the UI but it does not! _page.ProcessEvent(); /******* I don't want to have to do this. In my model I put a reference to the page to call this method on the page which set the DataContext to the Model again and refreshed the controls. There has to be a better way to do this. */ })); } }
Is there a better pattern I can implement to listen to the InputStream and process events which update my Model and up date the UI?
Tuesday, June 10, 2014 6:06 PM
All replies
-
Sorry, I'm not a Model/View/MVVM expert. One thing I never understand is that when these frameworks get in your way, folks seem to spend a lot of time trying to make the flow fit the framework rather than getting the app to work.
In layman's terms, what are you trying to do?Matt Small - Microsoft Escalation Engineer - Forum Moderator
If my reply answers your question, please mark this post as answered.
NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.Wednesday, June 11, 2014 7:06 PMModerator