Main Site Documentation

Anyone have any experience with Silver Light 4


#1

I created a demo to exchange data in near real time from the cobra to a browser.
http://code.tinyclr.com/project/377/using-adobe-flex-to-have-live-data-on-web-site/

This was done using Adobe Flex. I want to now make the same thing using Silverlgiht 4.
I have it working in demo mode, which of course does not request the policy file.
When i run it in release mode I am getting the policy file request on port 943, and i am sending it back to the browser but it is still not making the data connection on port 4503. In fact it never even fires the OnConnect method.

I do not know what the deal is here with the policy file for silver light. I am sending this back as the policy file.


<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from>      
        <domain uri="*"/>
      </allow-from>      
      <grant-to>      
        <socket-resource port="4502-4535" protocol="tcp"/>
      </grant-to>      
    </policy>
  </cross-domain-access>
</access-policy>


This is my silver light app.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Text;
using System.Threading;


namespace WebConnection
{

    public partial class MainPage : UserControl
    {
        public Socket socket;
        public DnsEndPoint endPoint;
        static AutoResetEvent autoEvent = new AutoResetEvent(false);

        public MainPage()
        {
            InitializeComponent();
            Debugwindow.Text = "Trying To Connect\n";

            try
            {

                endPoint = new DnsEndPoint("192.168.0.7", 4503);
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.SocketClientAccessPolicyProtocol = SocketClientAccessPolicyProtocol.Tcp;
                args.UserToken = socket;
                args.RemoteEndPoint = endPoint;
                args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
                
                socket.ConnectAsync(args);

            }
            catch (Exception a)
            {
                Debugwindow.Text += "Exception\n";

                Debugwindow.Text += a.ToString();

            }

        }

        public void OnConnect(object sender, SocketAsyncEventArgs e)
        {

            if (e.SocketError != SocketError.Success)
            {
                // this is an error condition!
                // check what error happened and what it means:
                // http://msdn.microsoft.com/en-us/library/system.net.sockets.socketerror.aspx

                Debugwindow.Text += e.ToString();

                return;
            }

            byte[] response = new byte[255];
            e.SetBuffer(response, 0, response.Length);
            e.Completed -= new EventHandler<SocketAsyncEventArgs>(OnConnect);
            e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
            socket.ReceiveAsync(e);
        }


        public void OnReceive(object sender, SocketAsyncEventArgs e)
        {
            string s = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);

            socket.ReceiveAsync(e);
        }

        public void sendbtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Text.Encoding encoding = System.Text.Encoding.UTF8;

                SocketAsyncEventArgs args = new SocketAsyncEventArgs();

                string s = textBoxSend.Text;

                byte[] data = Encoding.UTF8.GetBytes(s);

                args.SetBuffer(data, 0, data.Length);
                socket.SendAsync(args);

            }
            catch (Exception a)
            {
                Debugwindow.Text += "Exception\n";

                Debugwindow.Text += a.ToString();

            }

        }
    }
}


any ideas or suggestions ???


#2

Did you know that Pete Brown wrote a book on Silverlight 4?

Just sayin’…maybe Pete can offer some suggestions in his copious free time. :slight_smile:

In the meantime, maybe this would help?

http://timheuer.com/blog/archive/2008/04/06/silverlight-cross-domain-policy-file-snippet-intellisense.aspx

or this

http://blogs.msdn.com/b/silverlightws/archive/2008/03/30/some-tips-on-cross-domain-calls.aspx


#3

Definitely try this question over on the forums at http://silverlight.net. There are a lot more Silverlight experts there :slight_smile:

The policy file looks ok to me. You are sure it is being requested? Can you verify that the call to 943 is actually making it through? I want to eliminate firewalls as the potential issue at least for the socket file retrieval.

Next, can you see if 4503 is open in the firewall? Typically it isn’t by default.

Or, while testing, you could simply shut down your firewall (make sure it is really shut down, windows should be complaining about it to you)

Finally, if that’s all true and you’re still not sure what’s going on, download Wireshark and look at the messages going across. http://www.wireshark.org/

It’s like Fiddler, only lower-level.

Pete


#4

ya, i tried over there and i knew what was going to happen before i posted it. Once the word get out that the server is an embedded device everyone shuns away. I did try but with no luck there. They assume its the embedded device’s problem. Which is why i thought to post here because we all have more faith in our stuff.

As far as the rest. Yes i am getting the policy file request by my board and it is sending the policy file back to the browser. Verified by wire shark. Silver light Its just not continuing on to start the socket connection on port 4503. FWIW, if i run the app in debug more its all runs fine it creates the socket connection on port 4503 and i can exchange data. when i go to release mode is when it needs to get the policy file. Same thing applies to Adobe Flex.

I know this all works because i can create the exact same app in Adobe Flex which works just fine with no changes on the embedded device other that the difference in policy file.
So i dont know if the policy file in its present form is exactly what it needs, or something in the code for the silver light is not done correctly.


#5

Pete, is there not a chapter in your upcoming book about running Silverlight on NETMF? If not, you better get on it! :wink:


#6

You will never believe this, Got a amazon package in the mail today and finally got around to opening it up just now. Its pets book “Silverlight 4 in Action” So much for going to bed :wink:


#7

I’m going on memory here on a Windows CE app I did… I think it has to do with the port number. Try and connect your data session on port 400 or something low. I’ll try and dig up the article. Something related to a security policy.

This also drove me nuts because there’s no error.


#8

@ realiser

Silverlight is restricted to the ports it can use

@ jdal

It doesn’t look like the person on the forum shut down when you said it was on an embedded device. I was going to suggest the same thing they did: try this with a known working sockets server to help isolate the problem :slight_smile:

My coverage of sockets is, quite honestly, pretty thin in the book. I need to go speak at a code camp today, so I can’t look at this again until tonight.

It’s interesting that it runs in debug mode in the IDE. You did your wireshark verification in release mode, right? Are you hitting the same remote IP address when running from Visual Studio, or are you hitting localhost?

Finally, for grins, try changing your policy file to be more explicit. Include the actual domain that is serving up the silverlight app

  <allow-from>  
    <domain uri="http://someserver.com:1234/" />  
  </allow-from> 

Another thing to try to see if it is really a CAP problem: Turn your client app into an out-of-browser elevated trust application (make it OOB in the property settings, then in the OOB settings, say it requires elevated trust). Then right-click it when running and install/run it.

Pete


#9

Your socket server IS sending the cross domain file in UTF-8 format, right?

Are you getting access denied on the silverlight client?

Here are some other references I’ve found.

http://forums.silverlight.net/p/85656/562351.aspx/1?Re+Re+Re+Silverlight+2+Socket+Not+Connecting+AccessDenied+Exception

http://www.byteblocks.com/page/Using-Sockets-in-Silverlight-Diagnostics.aspx


#10

Actually this does not surprise me at all. I went through this when i first started mimicking a server when i was doing it with Adobe Flex. When you run either Adobe Flash/Flex or Silverlight in debug mode it will not ask for the policy file. It assumes that since its in debug mode its a trusted site. I did however find out last night that you can overide this feature in SL be unchecking “Enable Running application out of browser”. When i uncheck this it always asked for policy file in debug mode.

yup, policy file gets requested, board get it and responds with PF. all seen in wire shark.

I run it in release mode on my desktop 192.168.0.2, and it points to the devices IP as shown in the code “endPoint = new DnsEndPoint(“192.168.0.7”, 4503);” when it finally works and i put the site on the board i will change it to this. endPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4503);

I have tried many variations of this, does not mean i got the right one, but i would have thought just the opposite. make it more giving by using " * "

Honestly, i will have to look into that, i am not clear on UTF-8 Format.

no, it just never fires the OnConnect method for port 4503, it does in debug mode however.

That last link you send is very much what i got from the guy at MSDN, I created a windows console ap to mimic the server and handle the policy file I ran both of them on my computer and the console app got the policy file request and send it back but again there was firing of the OnConnect method. I was unable to use Wireshark to see the policy file sent back because it was all running on my PC and it never actually sent out on the pipe. Then i thought to run that server app on another computer so i can check the data. But that was over my head.


#11

@ jdal

Any luck yet? Could I get a copy of the complete solution (Cobra and SL) to test?


#12

@ Rajesh

Nope, tried it on 3 different platforms. Cobra, Netburner & Rabbit, then tried the Adobe Flex web site on all three and it worked just fine.

you can nab the project files here:
http://www.jdalsystems.com/backdoor/

I am not .netmf apt yet, so dont expect things to be elegant.


#13

This was fun :slight_smile:

First I tried to check that the policy file being returned was a good one. To do this I commented out the following line on PolicyListener.cs


//if (request == "<policy-file-request/>")

I then pointed the browser to http://192.168.2.200:943/policyfile.xml, and this is what I got


The XML page cannot be displayed 
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later. 

--------------------------------------------------------------------------------

Invalid at the top level of the document. Error processing resource 'http://192.168.2.200:943/policyfile.xml'. Line 1, Pos...

<?xml version="1.0" encoding ="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-fro...

I walked through the code and commented out the following line on PolicyListener.cs


//reply[reply.Length - 1] = 0;

I request the policy file again and this is what I got


  <?xml version="1.0" encoding="utf-8" ?> 
- <access-policy>
- <cross-domain-access>
- <policy>
- <allow-from>
  <domain uri="*" /> 
  </allow-from>
- <grant-to>
  <socket-resource port="4502-4506" protocol="tcp" /> 
  </grant-to>
  </policy>
  </cross-domain-access>
  </access-policy>

The SL application ran fine except for a load of cross thread exceptions from the debug prints:


Debugwindow.Text += e.ToString();

To print debug messages on SL use the following :


using System.Diagnostics;

and


Debug.WriteLine(e.ToString());


#14

so what are you saying you got it running ?

I wanted to print the result to the text box that was named "Debugwindow"
but it would not let me do that. I can only print to it when i am in public MainPage()


#15

Well to get it to run

Comment line 120 on PolicyListener.cs

//reply[reply.Length - 1] = 0;

Ah, I see about the DebugWindow. You will get cross thread exceptions if you try to update the UI from a different thread other than the one that created the control.

You can wrap the call as a delegate and push into the message queue for the main thread to process when possible.

Example:

Dispatcher.BeginInvoke(() => { 
                Debugwindow.Text += "Connected\n"; 
            });

#16

Sure enough that was it.

Strange, when using Adobe Flex, it would not run without doing that.

Thanks a million!!!