Сетевое соединение с приложениями UWP
Я получил два приложения Windows UWP. Один из них ("сервер") работает на Raspberry Pi 2 в Windows IoT (10586.0). Другой ("клиент") работает на любом устройстве Windows 10 в той же сети.
Я хочу, чтобы приложения "общались" друг с другом. На данный момент я просто хочу отправить простую строку с клиента на сервер. В дальнейшем сериализованные данные должны передаваться по сети.
Это код для сервера приложения:
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();
}
}
}
Как видите, я устанавливаю сетевое соединение с тем же приложением на том же хосте и отправляю строку "Test Self App". Это работает хорошо в течение довольно долгого времени, но через некоторое время я получаю сообщение об ошибке:
Исключение: "System.Runtime.InteropServices.COMException" в файле mscorlib.ni.dll
Информация WinRT: Соединение не может быть установлено, потому что целевой компьютер активно отказался от него.
Итак, это мой первый вопрос: что это за ошибка и как я могу это исправить?
Другое дело: я не могу установить сетевое соединение между сервером и клиентом. Я не знаю, что я делаю не так. Это код "Клиента":
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)
}
}
}
}
Когда я нажимаю на btn_Send, я получаю сообщение об ошибке
Попытка подключения не удалась, потому что подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, так как подключенный хост не смог ответить.
а также
Метод был вызван в неожиданное время. (Исключение из HRESULT: 0x8000000E)
Что я делаю неправильно? Может быть, я должен сказать, что я относительно новичок в программировании сетевых подключений, сокетов и т. Д.
Спасибо за любую помощь!
3 ответа
Вы должны попробовать использовать StreamSocket
API в UWP. Этот пример репо содержит код сервера и клиента: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/StreamSocket
Метод был вызван в неожиданное время. (Исключение из HRESULT: 0x8000000E)
Эта ошибка произошла для меня, когда я пытаюсь позвонить ConnectAsync
два раза подряд, я думаю, вы можете проверить свою логику или отладку, чтобы подтвердить в вашем случае.
Первая ошибка
Исключение: "System.Runtime.InteropServices.COMException" в файле mscorlib.ni.dll
Информация WinRT: Соединение не может быть установлено, потому что целевой компьютер активно отказался от него.
Это потому, что сокет все еще открыт с предыдущим запросом и еще не закрыт. Так что лови эту ошибку и попробуй и переподключи.
Попытка подключения не удалась, потому что подключенная сторона не ответила должным образом через некоторое время, или не удалось установить соединение, так как подключенный хост не смог ответить.
Это потому, что сервер и клиент находятся на одном компьютере, и я столкнулся с этой же проблемой, предположительно, вы можете запустить из командной строки с повышенными привилегиями
checknetisolation loopbackexempt -d -n= {package family}
решить это.
Это решение не сработало для меня. Таким образом, ваш сервер должен работать на пи, а клиент должен работать на настольном компьютере, чтобы Windows 10 UWP могла подключиться к нему. Насколько я могу судить, Windows 10 не допускает петлевого соединения для приложений UWP.
Если вы действительно хотите запустить сокет-сервер / веб-сервер node.js, для вас подойдут универсальные приложения Windows.
https://ms-iot.github.io/content/en-US/win10/samples/NodejsWU.htm
или же
RestUP https://github.com/tomkuijsten/restup
В зависимости от объема данных, о которых вы говорите, и конечного варианта использования, Amazon AWS IoT Platform может быть чем-то, на что стоит обратить внимание. Это довольно круто по ряду причин. Особенно мне нравится, что целевое устройство может быть отключено во время передачи.
Это бесплатно (250000 сообщений) в течение первого года и 5 долларов за миллион сообщений после этого. Каждый 512-байтовый блок считается за 1 сообщение.