3

I got two Windows UWP Apps. One of them (the "server") is running on a Raspberry Pi 2 on Windows IoT (10586.0). The other (the "client") is running on any Windows 10 device within the same network.

What I want is to get the apps to "talk" to each other. For the moment I just want to send simple String from the client to the server. Later on, serialized data should be transferred trough the network.

This is the code for the server App:

namespace LCARSHomeAutomation
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();

        try {
            EstablishNetworking();
            txb_Events.Text += "Server Running";
        }catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
        }

        
    }

    private async void EstablishNetworking()
    {
        await StartListener();
    }

    public async Task StartListener()
    {
        StreamSocketListener listener = new StreamSocketListener();
        listener.ConnectionReceived += OnConnection;

        listener.Control.KeepAlive = true;

        try
        {
            await listener.BindServiceNameAsync("5463");
            
        }
        catch (Exception ex)
        {
            if (SocketError.GetStatus(ex.HResult) == SocketErrorStatus.Unknown)
            {
                throw;
            }
            //Logs.Add(ex.Message);
            txb_Events.Text += ex.Message;
        }

    }

    private async void OnConnection(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
    {
        Stream inStream = args.Socket.InputStream.AsStreamForRead();
        StreamReader reader = new StreamReader(inStream);
        string request = await reader.ReadLineAsync();

        await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                   () =>
                                   {
                                        // Your UI update code goes here!
                                        txb_Events.Text += (String)request;
                                   });


    }

    private async Task ConnectSocket()
    {
        StreamSocket socket = new StreamSocket();

        socket.Control.KeepAlive = false;

        HostName host = new HostName("localhost");

        try
        {
            await socket.ConnectAsync(host, "5463");

            Stream streamOut = socket.OutputStream.AsStreamForWrite();
            StreamWriter writer = new StreamWriter(streamOut);
            string request = "Test Self App \n";
            await writer.WriteLineAsync(request);
            await writer.FlushAsync();

            socket.Dispose();
        }
        catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
            //Logs.Add(ex.Message)
        }


    }

    private async void btn_Send_Click(object sender, RoutedEventArgs e)
    {
        await ConnectSocket();
    }
    
}
}

As you can see, I'm establishing a network connection with the same app on the same host and send the string "Test Self App". This works fine for quite some time but after a while I get the Error:

Exception thrown: 'System.Runtime.InteropServices.COMException' in mscorlib.ni.dll

WinRT information: No connection could be made because the target machine actively refused it.

So, this is my first question: What is this Error and how can I fix this?

The other thing is: I'm not able to establish a network Connection between the server and the Client. I don't know, what I am doing wrong. This is the code of the "Client":

namespace LCARSRemote
{
/// <summary>
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
/// </summary>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    private async void btn_Send_Click(object sender, RoutedEventArgs e)
    {
        StreamSocket socket = new StreamSocket();

        HostName host = new HostName("localhost"); //Replace with coorect hostname when running on RPi

        try
        {
            try {
                await socket.ConnectAsync(host, "5463");
            }
            catch(Exception ex)
            {
                txb_Events.Text += ex.Message;
            }

            Stream streamOut = socket.OutputStream.AsStreamForWrite();
            StreamWriter writer = new StreamWriter(streamOut);
            string request = "Remote App Test";
            await writer.WriteLineAsync(request);
            await writer.FlushAsync();

            socket.Dispose();

        }
        catch (Exception ex)
        {
            txb_Events.Text += ex.Message;
            //Logs.Add(ex.Message)
        }

    }
}
}

When I click on the btn_Send, I get the error message

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

and

A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)

What am I doing wrong? Maybe I should say, that I'm relatively new in programming network connections, sockets etc.

Thanks for any help!

Community
  • 1
  • 1
drummercrm
  • 77
  • 2
  • 11
  • Have you changed the hostname to something sensible? Have you checked your firewall rules? – Rowland Shaw Apr 07 '16 at 13:55
  • I also tried wit the firewall turned off. I tried "127.0.0.1" as hostname, I also tried "minwinpc" (the name of the RPi in the LAN) but nothing seemed to work. – drummercrm Apr 08 '16 at 10:00
  • Have you tried with the IP address of your Pi? – Rowland Shaw Apr 11 '16 at 07:49
  • You didn't say that, your code says localhost (which obviously won't work as the client and server are on different hosts); you say you've tried localhost's IP (127.0.0.1) and the hostname, but not the actual IP. Have you actually tried your code with both running on the same host? – Rowland Shaw Apr 11 '16 at 11:15
  • I tried both: Server running on RPi with Client running on PC and also Server and Client running on PC. Depending on the scenario I changed the HostName in the Client Code. I tried with the hostname of the RPi and also the IP-Address of the RPi. When I try to send a message from the Server to itself (see the code, Task ConnectSocket) I can click for quite sometimes and then I get the message, that the "machine actively refused" the connection. – drummercrm Apr 11 '16 at 12:48

3 Answers3

1

You should try using StreamSocket API in UWP. This sample repo contents both server and client code: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/StreamSocket

A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)

This error happened for me when I try to call ConnectAsync twice in a row, I think you can check your logic or debug to confirm in your case.

thang2410199
  • 1,932
  • 2
  • 17
  • 18
  • I took a look at those examples but they weren't really helpfull. The errors are still existing. I also tried to use DataWriter / DataWriter instead of StreamReader / -Writer (like in above example) but it also didn't work. – drummercrm Apr 08 '16 at 10:02
1

The first error

Exception thrown: 'System.Runtime.InteropServices.COMException' in mscorlib.ni.dll

WinRT information: No connection could be made because the target machine actively refused it.

This is because the socket is still open with a previous request and has not closed yet. So catch this error and try and to reconnect.

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

This is because the server and client are on the same machine, I a running into this same problem supposedly you can run from an elevated command prompt

checknetisolation loopbackexempt -d -n= {package family} 

to resolve it.

This solution did not work for me. So your server must run on a pi and client must run on your desktop PC for windows 10 UWP to be able to connect to it. Windows 10 does not allow loopback connection for UWP applications as far as I can tell.

If you truly want to run a socket server/web server node.js windows universal apps might be a good approach

https://ms-iot.github.io/content/en-US/win10/samples/NodejsWU.htm

or

RestUP  https://github.com/tomkuijsten/restup
Stuart Smith
  • 1,931
  • 15
  • 26
0

Depending how much data you're talking about and what the end use case is, Amazon's AWS IoT Platform might be something to look at. It's pretty cool for a number of reasons. Specifically I like that the target device can be offline at the time of transmission.

It's free (250,000 messages) for the first year and $5 per one million messages after that. Every 512 byte block counts as 1 message credit.

ObjectType
  • 1,159
  • 10
  • 15
  • This is no possible solution for me because I want the Apps to talk to each other even when there is no internet connection. – drummercrm Apr 08 '16 at 06:11