I have a MVC .NET application that uses signalR.
I tried to download this client:
https://github.com/Gurgen/SignalR-.net-core-android-client
I ran it on my device. Pressed the connect button. But kept getting an exception.
Debugging it I found that I had to change this line
String connectionId = jsonElement.getAsJsonObject().get("connectionId").getAsString();
to this
String connectionId = jsonElement.getAsJsonObject().get("ConnectionId").getAsString();
I am already starting to feel like this client doesn't support v2.3.0 of the SignalR library in my .NET application. Any way the next exception is caused by this line:
JsonElement availableTransportsElements = jsonElement.getAsJsonObject().get("availableTransports");
I had a look at the JSON returned by SignalR and there is no such element as "availableTransports". This is what it returned
{ "Url":"/signalr/hubs/auth","ConnectionToken":"zzK0SAWXNEB1pLY2VYHWPYTMcyJIX8PnhKfLRP9fij5xbY2jDIaDyKuZQa5RvHt+KSe6h1PD9JC+RL7V2nhPzevktK781hL7ndAnZqAe3E12GawCVddFUI4R9FLDE//L","ConnectionId":"9cb5ff73-14d3-4e59-8b14-d92e47bbe948","KeepAliveTimeout":20.0,"DisconnectTimeout":30.0,"ConnectionTimeout":110.0,"TryWebSockets":false,"ProtocolVersion":"1.2","TransportConnectTimeout":5.0,"LongPollDelay":0.0 }
Ok my question, has anyone used this library? Or is there another Android library I can use that is compatible? I am new to SignalR but from what the server sent does the .NET application support websockets? I want my Android client to connect using websockets.
UPDATE
OK I have discovered that WebSocket Protocol feature was not installed in IIS. I have done that now and now this is what is returned, however the client cannot still connect to it.
{ "Url":"/signalr/hubs/auth","ConnectionToken":"6CkVnCK9KmbDemtXY/S+zCyBUdaYbaK8WmQxIw6+JxjeEzWCP7BPTiItqgvzu+hhaf6kIS4NlPln8LJLfS95UbUG4rF/8C6Y5D7eq2aKCLEU6up/c4l8YvMKheodRsKy","ConnectionId":"abe2cdca-e237-4cbd-8523-98af8c864b9b","KeepAliveTimeout":20.0,"DisconnectTimeout":30.0,"ConnectionTimeout":110.0,"TryWebSockets":true,"ProtocolVersion":"1.2","TransportConnectTimeout":5.0,"LongPollDelay":0.0}
That is a step closer as now TryWebSockets is true.
Related
I coded a MAUI Blazor App which connects to MongoDB Atlas and loads some Data in the App. Everything works fine if I run the App on a Windows PC. But if I compile/run the same code on an Android device I get this error in the development tools:
**blazor.webview.js:1 List of configured name servers must not be empty. (Parameter 'servers')**
at DnsClient.LookupClient.QueryInternal(DnsQuestion question, DnsQuerySettings queryOptions, IReadOnlyCollection`1 servers)
at DnsClient.LookupClient.Query(DnsQuestion question)
at DnsClient.LookupClient.Query(String query, QueryType queryType, QueryClass queryClass)
at MongoDB.Driver.Core.Misc.DnsClientWrapper.ResolveTxtRecords(String domainName, CancellationToken cancellationToken)
at MongoDB.Driver.Core.Configuration.ConnectionString.Resolve(Boolean resolveHosts, CancellationToken cancellationToken)
at MongoDB.Driver.MongoUrl.Resolve(Boolean resolveHosts, CancellationToken cancellationToken)
at MongoDB.Driver.MongoClientSettings.FromUrl(MongoUrl url)
at MongoDB.Driver.MongoClientSettings.FromConnectionString(String connectionString)
at MongoDB.Driver.MongoClient..ctor(String connectionString)
at MBz_MauiAndMongoDb.Pages.Index.OnInitializedAsync() in **C:\Users\XXX\source\repos\MBz_MauiAndMongoDb\MBz_MauiAndMongoDb\Pages\Index.razor:line 23
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()**
The error occures at is moment:
var client = new MongoClient(MongoDbConnectionString);
var db = client.GetDatabase(MongoDbName);
The ConnectionString works perfect if run on a Windows maschine. The ConnectionString looks like this:
"mongodb+srv://AtlasUser: myUserName+myCluster/test?retryWrites=true&w=majority&ssl=true"
I use the MongoDB.Bson and the C# MongoDB.Driver.
In the Documentations I only find the connectionString Syntax I use. But that seems to NOT work with MAUI App on a Android-Device! If I just use "mongodb://AtlasUser:..." without the 'srv' I get a timeout error. Or is it a problem with permissions under Android, I didn't change the original MAUI Blazor template stuff in that regard. Any Ideas?
Thx for your Help!
It's simple: on WebAssembly you cannot do something impossible to do using JavaScript in a browser.
The mongodb:// protocol is a TCP based protocol and cannot be connected from any kind of code running in a browser. This limitation is not specific to Blazor.. any other WebAssembly like Uno Platform will have the exact same limitations.
You have 2 options to circumvent this:
You connect to a server part of your application using http/https (it could be REST API, WebSockets, SignalR or whatever else running on http) and, from there, you connect to the MongoDB server.
You connect directly to the MongoDB server using a REST interface -- but I'm pretty sure the MongoDB.Driver won't be able to use them and you'll have to build your queries by yourself.
Disclamer: I'm a senior architect at Uno Platform working on the WebAssembly platform.
This answere from the MongoDB Forum solved my problem:
Welcome back to the MongoDB Community Forums. I see that you’re having problems running a MAUI Blazor app using the MongoDB .NET/C# Driver. The error you’ve encountered is coming from one of our third-party dependencies, DnsClient.NET, which we use for SRV and TXT DNS lookups. The error indicates that autodiscovery of nameservers wasn’t successful. You can read more about it in DnsClient.NET issue #143.
While in theory you could manually configure DNS nameservers when instantiating the LookupClient instance, our driver does not expose the ability to supply arguments to the LookupClient constructor.
Two options:
Figure out why DnsClient.NET cannot autodiscover the configured DNS nameservers.
Use the standard connection string format (e.g. mongodb://) instead of the DNS seed list connection format (e.g. mongodb+srv://).
The latter option works because we only use DnsClient.NET for SRV and TXT lookups. A, AAAA, CNAME, and other DNS records are performed automatically by the operating system. Note that simply removing +srv from the connection string is not sufficient. The hostnames are different. If you’re using MongoDB Atlas, go to your cluster page, select Connect, Connect your application, C# / .NET 2.4 or later, and you should see a connection string that looks like:
mongodb://<username>:<password>#cluster0-shard-00-00.CLUSTER_NAME.mongodb.net:27017,cluster0-shard-00-01.CLUSTER_NAME.mongodb.net:27017,cluster0-shard-00-02.CLUSTER_NAME.mongodb.net:27017/?ssl=true&replicaSet=REPLSET_NAME&authSource=admin&retryWrites=true&w=majority
I'm trying to create a websocket connection to my Phoenix app from an Android client. I'm trying to use this library but I'm running into this issue and I'm unable to successfully join a channel.
Upon reviewing the source code of the above java phoenix client library, it looks like the initial request from the client to connect to the socket is made with http schema and not ws (the source code explicitly changes the provided url to make sure it always uses http). It's not clear to me how this would work without additional configuration in my Phoenix app: if a socket connect request is made to http://localhost:4000/socket, the request will fail because there is no route for /socket when the schema is http.
There's nothing in the library docs that says any additional config is required in my Phoenix app to make this work, but I don't see how it could work for the reason stated above.
Does a Phoenix app have built in handling for the connection upgrade, etc, required on handshake as specified here?
As a note, I have no issues making websocket connections from my javascript web client to my Phoenix backend.
Any suggestions are appreciated!
Have you tried using the default path for a channel http://localhost:4000/socket/websocket ?
I am working on the Android client implementation that connects via websocket to a server. I've just enabled HTTPS on the server instance and now I am receiving this issue:
W/System.err: com.neovisionaries.ws.client.HostnameUnverifiedException: The certificate of the peer (CN=otherdomain.com) does not match the expected hostname (domain.com)
at com.neovisionaries.ws.client.SocketConnector.verifyHostname(SocketConnector.java:171)
at com.neovisionaries.ws.client.SocketConnector.doConnect(SocketConnector.java:126)
at com.neovisionaries.ws.client.SocketConnector.connect(SocketConnector.java:83)
at com.neovisionaries.ws.client.WebSocket.connect(WebSocket.java:2152)
at com.neovisionaries.ws.client.ConnectThread.runMain(ConnectThread.java:32)
at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
It seems that the websocket client is finding mismatched server host names.
Some other related info:
otherdomain.com is a different one of our URLs. It is pointed to separate instance of the same web application running on the same server as domain.com which is the app I am currently working on.
My code is logging the URL that it is connecting to and I can see that it is correctly referencing domain.com:
connecting to: wss://domain.com?session_key=TheCorrectSessionKey
As noted otherdomain.com is another instance of the same web application. That instance already previously had HTTPS enabled and everything is working properly with that instance. The same client code I am using now is able to connect successfully to this instance.
The same web application has a front end page that also connects to the websocket via wss://. This is working properly in both Chrome and Firefox browsers for domain.com, as far as I can tell the only client having issues is the Android client, and it's only the domain.com variant of the app having issues, the otherdomain.com one seems to be working fine.
I found this issue opened on the library I am using for websockets. But I'm not 100% sure if my problem is related to it, but it may be. In particular someone states:
Not being able to connect to a WebSocket-enabled server domain unless it is also configured to be the default server on the website.
I assume only one site can be default, and perhaps otherdomain.com got set to default since it was completed first. This is all a bit over my head though to be honest, I'm not sure if this is relavent or not.
I am developing a Xamarin mobile Android app. For data access, the app uses a Portable class library to make webservice calls to the back end. I’m using the Portable class library so that I can share it with an iOS version of the mobile app later. The data is sensitive and requires SSL for all communications which is configured in the WebAPI web service project. It uses oAuth for authentication.
The challenge I’m running into is that the initial request to authenticate is failing when I run it locally with the following error:
System.Net.Http.HttpRequestException: An error occurred while sending the request
System.Net.WebException: Error: TrustFailure (The authentication or decryption has failed.)
System.IO.IOException: The authentication or decryption has failed.
Some additional information:
I am using the following built in Visual Studio emulator and version - Android_Accelerated_x86 (Android 6.0 – API 23).
I am currently running it on localhost and following is the code snippet for this call:
HttpClient client = new HttpClient(new NativeMessageHandler())
{
BaseAddress = new Uri("https://10.0.2.2:44342/") // I also tried installing it on IIS and using port 443 on localhost. Same problem.
};
var content = new StringContent("grant_type=password&username=[USER_NAME]&password=[PASSWORD]", Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsync("Token", content).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var stuffList = JsonConvert.DeserializeObject<List<Stuff>>(data);
return stuffList;
}
else
{
return new List<Stuff>();
}
The call works when I test it through Fiddler on localhost, so I know that everything is configured correctly on the web service end and with authentication. But from the emulator my understanding is that I need to use IP address 10.0.2.2. I have create a self-signed cert and that hasn’t seemed to help.
I have also attempted to use Fiddler as a middleman, but I’m not seeing any activity in Fiddler when I run the app locally. I have also tried to change the network settings of the emulator, but it doesn’t appear to be having any affect. The base emulator seems to be fairly limited in these settings, but I also don’t want to pay for a more advanced one at this point in time. I have seen a number of posts with similar issues, but none of the existing recommendations that I have found are helping. Any help would be greatly appreciated!
In my XMPP chat application, I am using ASMACK library 4.0.6 on the Android client side.
I want to retrieve offline messages when an XMPP connection is established. For that, first I check whether the server has support for flexible retrieval. The server always returns false. We enabled the offline module in MongooseIM server. But why am I getting false from server?
if (!offlineMessageManager.supportsFlexibleRetrieval()) {
Log.i("Offline messages not supported","" + offlineMessageManager.supportsFlexibleRetrieval());
return;
}
If I try with pidgin client, I get offline messages..
Disclaimer: I work on MongooseIM.
Guessing from the API you're trying to use it implements XEP-0013 - MongooseIM doesn't support this XEP. Ensure what protocol .supportsFlexibleRetrieval() really uses underneath.
MongooseIM supports XEP-0313 version 0.2 and will support the newest version of this XEP. Verify whether your client library supports this XEP and which version of it. The relevant module to run on the server is mod_mam. Please refer to the MongooseIM wiki on GitHub, since its configuration is a bit complex.
Alternatively, you can rely on mod_offline automatically pushing the offline messages when a resource connects.