DCSIMG
PowerPoint Remote Control for Windows Phone [Open Source] - StudentGuru Larissas - Student Groups - StudentGuru

PowerPoint Remote Control for Windows Phone [Open Source]

PowerPoint Remote Control for Windows Phone

 

Σε αυτό το blog post θα δούμε τα βασικά βήματα που χρειάζονται για να δημιουργήσουμε μια εφαρμογή που να επικοινωνεί με το PC με sockets με μια μικρή επεξήγηση.

Η λογική πίσω από μία τέτοια εφαρμογή είναι η δημιουργία μίας client εφαρμογής για Windows Phone η οποία θα στέλνει συγκεκριμένες εντολές μέσω sockets σε μία server εφαρμογή η οποία θα λαμβάνει τις εντολές και θα εκτελεί αντίστοιχες εντολές στο PC. Δεν θα ασχοληθούμε σε αυτό στο blog post με το γραφικό περιβάλλον της εφαρμογής γιατί αυτό είναι κάτι που ο καθένας μας μπορεί να αποφασίσει να το κάνει διαφορετικά. Θα προσπαθήσουμε όμως να εξηγήσουμε τις βασικές έννοιες για τον κώδικα που χρησιμοποιούμε για να επιτύχουμε την επικοινωνία μέσω sockets!

Στην client μεριά ,δηλαδή στην εφαρμογή για Windows phone, θα πρέπει να δημιουργήσουμε μία κλάση έστω SocketClient.cs η οποία θα είναι υπέυθυνη για την σύνδεση του κινητού σε ένα συγκεκριμένο socket και την αποστολή δεδομένων σε αυτή. Ας δούμε λίγο τον κώδικα της κλάσης αυτής.

 

public class SocketClient
    {
        Socket socket = null;
        
        public void Connect(string hostName, int port)
        {
            IPEndPoint hostEntry = new IPEndPoint(IPAddress.Parse(hostName), port);
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs { RemoteEndPoint = hostEntry };
            socket.ConnectAsync(socketEventArg);
        }

        public void Send(string data)
        {
            if (socket != null)
            {
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs
                    { RemoteEndPoint = this.socket.RemoteEndPoint, UserToken = null };
                byte[] payload = Encoding.UTF8.GetBytes(data);
                socketEventArg.SetBuffer(payload, 0, payload.Length);
                socket.SendAsync(socketEventArg);
            }
        }
    }

Όπως βλέπεται σε αυτή την κλάση έχουμε δημιουργήσει δύο μεθόδους. Η πρώτη είναι η μέθοδος Connect. Με αυτή την μέθοδο λέμε στην εφαρμογή μας σε ποια IP διεύθυνση θλελουμε να στείλει τα δεδομένα και συγκεκριμένα σε ποιο ακριβώς Port σε αυτήν την IP. Αφού συνδεθούμε λοιπόν με τoν υπολογιστή μας συνεχίζουμε υλοποιώντας την μέθοδο Send η οποία θα στέλνει τα δεδομένα μας. Αφού υλοποιήσουμε την κλάση αυτή το μόνο που μένει είναι στην εφαρμογή μας να δημιουργήσουμε ένα στιγμιότυπο της κλάσης και να χρησιμοποιήσουμε μία φορά μόνο την Connect για να συνδεθούμε και στην συνέχεια την Send κάθε φορά που θέλουμε να στείλουμε κάτι.

 

Ας δούμε τώρα τι γίνεται από την μεριά του υπολογιστή.

Socket listener;
        public  void StartListening()
        {
            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 8221);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(localEndPoint);
            listener.Listen(10);
            listener.BeginAccept(AcceptCallback, listener);
        }

        public  void AcceptCallback(IAsyncResult ar)
        {
            Dispatcher.BeginInvoke(new Action(()=>txtStatus.Text = "Connected"));
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);
            StateObject state = new StateObject {workSocket = handler};
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
        }

        public  void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            int bytesRead = handler.EndReceive(ar);
            content = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);
            Dispatcher.BeginInvoke(new Action(()=>txtData.Text = content));
            Dispatcher.BeginInvoke(new Action(() => DecideWhatToDo()));
                
            if (content != "60")
            {
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, ReadCallback, state);
            }
            else
            {
                Dispatcher.BeginInvoke(new Action(() => txtStatus.Text = "Not Connected"));
                listener.BeginAccept(AcceptCallback, listener);
            }
        }

Στην μεριά του υπολογιστή για να λάβουμε τα δεδομένα υλοποιούμε 3 μεθόδους. Όμως στην ουσία υλοποιούμε μόνο μία μιας που οι δύο είναι ασύγχρονα callbacks γιατί χρησιμοποιούμε ασύγχρονες μεθόδους για να αποφύγουμε να "κολλήσει" το UI μας. Έτσι υλοποιούμε στην μέθοδο StartListening την οποία καλούμε όταν ξεκινήσει το πρόγραμμά μας και της όρίζουμε το socket το οποίο πρέπει να "παρακολουθεί" ώστε να καταλάβει πότε θα έρθουν δεδομένα. Στο τέλος θα προσέξετε ότι σε μία if γίνετε ένας έλεγχος για την περίπτωση που στα δεδομένα έχουμε τον αριθμό 60. Το 60 το έχω επιλέξει εγώ ως ένα δεδομένο ελέγχου για την περίπτωση που αποσυνδεθεί ο client. Στην εφαρμογή μας στο Windows Phone βάζουμε μια εντολή όταν κλείνει να κάνει Send("60"). Αυτός ο έλεγχος είναι απαραίτητος γιατί αν ο client αποσυνδεθεί και δεν πούμε στον server μας να ξεκινήσει να περιμένει πάλι για καινούρια σύνδεση θα τερματίσει. Έτσι με αυτόν τον έλεγχο και με ένα προκαθορισμένο πχ νούμερο μπορούμε εύκολα να κάνουμε το πρόγραμμά μας να καταλάβει ότι ο client αποσυνδέθηκε και να του πούμε να ξεκινήσει πάλι να περιμένει για καινούρια σύνδεση!

Εδώ μπορείτε να βρείτε τα project με ολοκληρωμένο τον κώδικα για τις εφαρμογές! http://sdrv.ms/Ip54bZ

Για οποιαδήποτε απορία αφήστε comment η στείλτε μου email στο konsloun -at- hotmail dot com!