I am new to Xamarin Forms. I am building an app which consumes a web service. I am getting HttpRequestException while trying to connect to server. The InnerException throws System.Net.WebException: Error: NameResolutionFailure at System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult).
The code that crash is:
public async Task<IEnumerable<Bono>> GetAll()
{
var Url = Constants.baseUrl + "cliente/1/bonos";
HttpClient cliente = new HttpClient();
var bonos = await cliente.GetStringAsync(Url);
return JsonConvert.DeserializeObject<List<Bono>>(bonos);
}
I am using VS for Mac. The same works for Xamarin.iOS. Any suggestion on this?
If the endpoint that you are trying to consume is hosted on your local machine and you are running the application in the local android emulator, you could use the following IP address to reach the host machine from the emulator:
http://10.0.2.2
Of course this will break iOS but it's the IP that can be used from an android emulator to access the host. As an alternative you could use ngrok which can create a publicly accessible tunnel to an endpoint hosted on your local machine and then access the public endpoint from the android application. It could be helpful during development if you want to avoid hosting your endpoint to a network location that can be accessed from the emulator.
Related
I have a very simple API in C# for test purposes. The API is created in a Windows Forms project
listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
LogUtils.appendInfo("Listening for connections on: " + url);
//Handle requests
Task listenTask = HandleIncomingConnections();
listenTask.GetAwaiter().GetResult();
If I call http://localhost:8080/ I get response from API.
The problem is that if I call the API from another PC using the external IP address http://ExternalIp:8080/
I get this error:
Bad Request - Invalid Hostname HTTP Error 400. The request hostname is
invalid
What I have tried:
I have put in the firewall a rule for port 8080 in incoming connections.
I have tested with the ISS server that brings Windows Server 2019 off and on.
I have created a 'applicationhost.config 'file in 'C:\Users\myUser\source\repos\myProyect.vs\proyectname\config' for <'binding protocol="http" bindingInformation=":8080:" /> because my project not have applicationhost.config file.
As #PanagiotisKanavos commented I can not use "localhost" in "listener.Prefixes.Add" for external request.
Solved by:
http://*:8080/
And run Visual Studio as administrator.
I'm developing a really simple MQTT Android client, so I can connect to it with an MQTT Server I created in C# using the MQTTnet library.
I first tested the C# broker with a C# client and Node-RED and it worked just fine.
I also tested the Android Client with CloudMQTT following this tutorial, and it also worked perfectly fine.
But when I tried to connect my Android Client to the C# Server, the Android Client gave me the following error:
Mqtt: Failed to connect to: tcp://localhost:1883 It's not possible to connect to server (32103) - java.net.ConnectException: Connection refused
I'm using BlueStacks as an emulator (I will try to test it in a real Android device asap). I tried to restart the emulator (as said in Paho Mqtt Android connecting to broker fails with (32103)) but it didn't work either.
The code for the Android Client is exactly the same as in the tutorial I mentioned earlier (using the Paho-MQTT library), but changing the serverUri and subscription topic:
final String serverUri = "tcp://localhost:1883";
final String subscriptionTopic = "step/time";
The app only has a TextView where I set the received messages.
As for the C# server, I'm sending a timestamp every 10 seconds. This is my code:
namespace MQTTServerExample
{
class Program
{
static void Main(string[] args)
{
serverAsync();
}
private static async Task serverAsync()
{
// Starting the MQTT Server
var mqttServer = new MqttFactory().CreateMqttServer();
var options = new MqttServerOptions();
//Saving retained application messages
options.Storage = new RetainedMessageHandler();
// Publishing messages
await mqttServer.StartAsync(options);
Console.WriteLine("### SERVER CONNECTED ###");
Console.WriteLine("Press ENTER to exit.");
MqttApplicationMessage message;
#pragma warning disable CS4014
Task.Run(async () =>
{
while (true)
{
message = new MqttApplicationMessageBuilder()
.WithTopic("step/time")
.WithPayload(DateTime.Now.ToString())
.WithExactlyOnceQoS()
.WithRetainFlag(true)
.Build();
await mqttServer.PublishAsync(message);
await Task.Delay(10000); // Every 10 seconds
}
});
#pragma warning restore CS4014
//await mqttServer.PublishAsync(message);
Console.ReadKey();
await mqttServer.StopAsync();
}
}
I'm new to connection protocols and I still don't understand them clearly, so I was hoping you could help me understand this problem.
A java.net.ConnectException: Connection refused exception means that there is no service listening on the host and port you are trying to connect to, for example because the host address or port is wrong, or the service is not started.
Using "tcp://localhost:1883" as server address only works if the server runs on the same machine as the client (i.e. in your case the Android device). You should use the server's name or IP address.
I'm going to guess that your C# broker is only listening on localhost not the external IP address of the machine hosting it.
This would work when ran the C# client on the same machine, but not when you use the external IP address from the Android client.
The other possible option is that you are running a firewall on the broker machine which is stopping the Android client connecting.
I have a stateless service acting as an api gateway along with a stateful service that is deployed to Azure on a secured service fabric cluster (using Azure AD). I'm exposing a websocket endpoint (wss). When connecting from my client app (console application using a ClientWebSocket instance), I'm getting "Unable to connect to the remote server" with an inner exception stating: "Authentication failed because the remote party has closed the transport stream." This happens if I attach the SSL cert (from my local machine) that the cluster is secured with, or if I pass my NetworkCredentials in with the ClientWebsocket object when I create it. The endpoint I'm hitting looks like this: wss://blahblahblah.cloudapp.azure.com:19000/mygateway/data. When I tested this code locally before I secured it, I was able to connect. Once I got this deployed successfully to a secured cluster, my client app won't connect. Is there something else I need to provide from the client side to get through the security?
public async Task<bool> ConnectAsync(Uri serviceAddress)
{
this._clientWebSocket = new ClientWebSocket();
using (CancellationTokenSource tcs = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
try
{
_clientWebSocket.Options.ClientCertificates = GetCertForRemoteAuthentication();
_clientWebSocket.Options.Credentials = new NetworkCredential{Domain = "mydomain", Password = "somepassword", UserName = "username"};
await this._clientWebSocket.ConnectAsync(serviceAddress, tcs.Token);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
return true;
}
By specifying a specific port and hitting that endoint to our stateful service, as opposed to our service fabric application endpoint (on port 19000) - we were able to get through to our service. Also had to add some code on the server code to make sure we were binding the server certificate to the websocket listener on the server side. That solved our issue.
I've got a standalone on-premise Service Fabric Cluster that is secured using Windows Authentication.
In this application I have a ASP.NET Core WebApi Stateless service that tries to communicate with another stateless service via the remoting. Unfortunately I'm getting the following error when the WebApi service tries to RPC to the stateless service:
System.AggregateException: One or more errors occurred. ---> System.Fabric.FabricConnectionDeniedException: Not authorized to connect ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071C43
at Microsoft.ServiceFabric.FabricTransport.NativeServiceCommunication.IFabricServiceCommunicationClient2.EndRequest(IFabricAsyncOperationContext context)
at Microsoft.ServiceFabric.FabricTransport.Client.FabricTransportClient.EndRequest(IFabricAsyncOperationContext context)
at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)
--- End of inner exception stack trace --
Futhermore, I can confirm that
When deploying this same application to a "development cluster" (i.e. either my local machine or another a remote Service Fabric cluster running all it's Nodes on one machine), I don't get the error - hence potentially an issue with the AD accounts I've used to setup my multi-machine cluster (I'm using a machine group account).
When creating the Client Proxy, I do setup the Security Credentials to use windows authentication - i.e.
var transportSettings = new FabricTransportRemotingSettings
{
SecurityCredentials = new WindowsCredentials()
};
Func<IServiceRemotingCallbackClient, IServiceRemotingClientFactory> clientProxyFactory = c => new FabricTransportServiceRemotingClientFactory(transportSettings);
var serviceProxyFactory = new ServiceProxyFactory(clientProxyFactory);
TService clientProxy = serviceProxyFactory.CreateServiceProxy<TService>(uri);
return clientProxy;
In the above code, if I instead use:
SecurityCredentials = new NoneSecurityCredentials() then I get a similar FabricConnectionDeniedException but the message is slightly different saying that the Client is not authorised to connect. This makes sense - but again, potentially indicates that there is an issue with my transport settings...
I have an Azure Cloud Service with a worker role that starts an OWIN web app on startup, which uses SignalR.
Separately, I have a console project that uses the SignalR client library to connect to this worker role and listen for events.
Everything is working when I run the client and the service locally using the Azure emulators.
When I publish the cloud service and point the console application to it and try to connect, I get the following in the SignalR trace logs:
WS Connecting to: ws://myapp.cloudapp.net/signalr/connect?clientProtocol=1.4&transport=webSockets&connectionData=[{"Name":"MessageBusHub"}]&connectionToken=...
OnError(System.Net.WebSockets.WebSocketException (0x80004005): An internal WebSocket error occurred. Please see the innerException, if present, for more details. ---> System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
It then proceeds to try again using server sent events and long polling with the same error each time.
I'm using the following endpoint in my Cloud service config:
<Endpoints>
<InputEndpoint name="SignalREndpoint" protocol="http" port="80" localPort="80" />
</Endpoints>
And here is how I create my OWIN web app:
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["SignalREndpoint"];
string webAppUrl = $"{endpoint.Protocol}://{endpoint.IPEndpoint}";
_webApp = WebApp.Start<Startup>(webAppUrl);
Finally, here's how I configure SignalR:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.UseServerAuthentication();
GlobalHost.DependencyResolver.UseServiceBus(CloudConfigurationManager.GetSetting("ServiceBusConnectionString"), "SignalRMessageBus");
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
});
}
}
In the client project I am simply using a HubConnection to connect using the following URL for local testing, http://localhost:80, and the following URL for connecting to the cloud instance, http://myapp.cloudapp.net
I'm not sure what's different between the actual Azure instance and my local emulator that's causing it to not work in the cloud.
Interestingly, if I use the browser to connect to the URL http://myapp.cloudapp.net/signalr/hubs, it works and returns the JS proxy file.
Have you tried using TCP instead of HTTP as a protocol?
I am not a SignalR expert in any way, but I know about it. When we host our server (XSockets.NET) on Azure worker roles we configure the protocol to be TCP (not HTTP).
Have no idea why it would work on localhost though.
Another thing to consider is if the worker role supports websockets? SignalR requires IIS8+ for websocket support and I have no idea if you have access to that in a worker role. There are no options in Azure to turn websockets on/off on a worker role (from what I can see). So my guess is that there is no Microsoft WebSockets in the worker role. By I might be wrong here!
EDIT: Looked at one of my instances and saw that I can change OS and that the default one is 2012 Server. So Microsoft websockets should be available!