Can't communicate with service using DNS in service fabric - c#

I'm trying to get a stateless service to send a value to another, just to achieve communication between services by using the DNS-service in service fabric. I've tested both applications with postman, and they work fine. I'm following this tutorial where it seems pretty straight forward to do this.
The DNS-service is enabled:
The stateless service has a DNS-name:
The DNS-name is configured in the ApplicationManifest.xml
<Service Name="SocketService"
ServiceDnsName="SocketService.TimeSeriesActorApplication"
ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="SocketServiceType"
InstanceCount="[SocketService_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
I then try to send a http get to the service, just like in the tutorial.
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://socketservice.timeseriesactorapplication:8712/api/");
var response = await client.GetAsync("values");
}
But I get an exception:
WebException: The remote name could not be resolved: 'socketservice.timeseriesactorapplication'
This happens both when I use port 8080 like the tutorial suggests, and when I use the port I specify in ServiceManifest.xml.
<Endpoints>
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8712" />
</Endpoints>
What am I missing here?
Update:
Using localhost instead of dns-name also works fine.
Issue on Github: Unable to resolve service DNS name #332

I see you are running service fabric 5.6.210. The recent 5.6.220 release (https://blogs.msdn.microsoft.com/azureservicefabric/2017/06/20/release-of-sdk-2-6-220-and-runtime-5-6-220-refresh-for-windows/) contains some fixes for the DNS service. Note that even though I am running 5.6.220, I have noticed that the DNS name resolution does not always seem to start working straight away after deployment on my local machine (I have to redeploy or wait a few minutes). If you are running locally you can test the name resolution in a terminal window - just ping your service's DNS name.

I fixed it by using ipconfig /flushdns to refresh DNS.
I also found that local IP is the first DNS server in my DNS chain.

Related

SignalR app starts, runs on http but not on https: Unexpectedly closed connection

I have a self-hosted SignalR application in a Windows Service built with VS2015 FW 4.6, SignalR 2.3.0. This has been working fine for more than 2 years using ports 6286 (https) and 6287 (http) and "*" for the IP. I wanted to switch these ports to 80 and 443 respectively and apply a wild-card certificate to 443. Since there are web sites using the certificate on IP 192.168.100.7 I added another IP address (192.168.100.3) to my server applied the certificate with:
netsh http add sslcert ipport=192.168.100.3:443 appid={12345678-db90-4b66-8b01-88f7af2e36bf} certhash=xxxxxxxxxxxxxxxxxxxxxxxxx
I can verify the success with:
netsh http show sslcert ipport=192.168.100.3:443
So I start the WebApps with the following:
SignalR = WebApp.Start("http://192.168.100.3:80/");
SignalRSSL = WebApp.Start("https://192.168.100.3:443/");
They seem to start fine, no errors and if I use http://192.168.100.3/signalr/hubs it works fine. However, https://192.168.100.3:443/signalr/hubs gives the "Unexpectedly closed connection" error.
What have I done wrong, is there something else to set for https?
My error... I was using the internal IP's and corresponding external IP's to test this. What I realized is that the wild-card certificate is not tied to an IP, it's tied to a domain! So, I created an A record for the IP with the wild-card's domain and it worked.
However, I now have a different problem in that it's trying to negotiate with the web server's domain and not the signalR domain to send a message!
https://webserverdomain/signalr/negotiate?clientProtocol=1.5....
I don't know where it's picking the web server's name up but it's different enough that it's probably a topic for another post.

WCF Endpoint Address using https (WebHttpBinding)

I need to modify a WCF endpoint binding address. Here is some background on the issue:
I have an NT class service (if it matters, not a webservice). It creates a System.ServiceModel.ServiceHost with an Endpoint whose endpoint address is created this way:
var epa = new EndpointAddress(string.Format("https://localhost:{0}/ServiceAPI/", 8181));
The binding used for the ServiceEndpoint is a WebHttpBinding with Mode=WebHttpSecurityMode.Transport (i.e. https).
When the ServiceHost is opened, I can go to a command prompt, and do "Netstat -a" and see the address bound to the Listen as 0.0.0.0:8181.
So far, no problem. However, a large customer has raised a "security issue" with the fact that because the WCF "listen" is on address 0.0.0.0 instead of 127.0.0.1, that a potential attacker can connect to that address from an external machine. The test that they have constructed is to use telnet 8181 from an external machine, and if the connect occurs, then the test fails. The change request is to modify the service to "listen" on 127.0.0.1:8181 so that the only possibility of connecting to that port is from the local machine.
I have done a fair amount of modifications in an attempt to get WCF to "listen" on "127.0.0.1" instead of "0.0.0.0". In all of my attempts the only way to do this is to set HostNameComparisonMode to "Exact" and create the endpoint address in this way:
var epa = new EndpointAddress(string.Format("https://127.0.0.1:{0}/ServiceAPI/", 8181));
(Actually, as an aside, if I use a different binding such as NetTcpBinding, the above EndPointAddress construction will bind to address "127.0.0.1:8181" without altering HostNameComparisonMode. It only switches internally to "0.0.0.0:8181" when I use WebHttpBinding, and fail to set HostNameComparisonMode=Exact.)
However, this (setting HostNameComparisonMode=Exact) causes a breaking complication due to the fact that existing 3rd party code has already been developed that attempts to (onboard the server) connect to "https://localhost:8181/ServiceAPI", and when HostNameComparisonMode is set to "Exact", WCF only ever returns http error 506 to any request due to the difference between "localhost" and "127.0.0.1".
What I am currently looking for is either a means of setting up WCF to bind to "127.0.0.1:8181" (as determined by netstat -a) with the HostNameComparisonMode still set to the default "StrongWildcard" setting. Or barring any possibility of there being a way to do that, another creative suggestion to cause connects coming from external machines to be unable to connect to that port. (The test would be to use "telnet servername 8181" from a different machine, and it fail to connect.)
Any ideas? Thanks!
if i understand you right, you want to connect from remote machine to this address, so can you try BasicHttpBinding? Also you can try to host it at: "https://localhost:{0}/ServiceAPI/", 8181" Correct pls if i understand you wrong.

'No connection could be made because the target machine actively refused it'

I am working on a 'Smart Device Project' using .Net Framework 3.5. I am trying to connect to some Java SOAP services on a remote server.
In order to do that, I added 'Web References' to my project.
When I try to call my web service I get a WebException 'Unable to connect to the remote server' with the inner exception being 'No connection could be made because the target machine actively refused it'.
I searched quite a lot on the Web and StackOverflow and found a lot of ASP configuration and 'Unavaliable port' answers, but as I have another application using the exact same Service successfully, I can't get why the new one isn't getting through (It did sometimes through my tests so I suppose my client implementation isn't that bad)
I tried to look if there was some connection issue on the port by using some TcpClient:
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
try
{
client.Connect("myServerName", 8087);
MessageBox.Show("Success");
} catch (Exception ex)
{
MessageBox.Show("Failure");
}
finally
{
client.Close();
}
This connection succeed.
Here is a sample on how I call my WebService:
WSServiceExtended srv = new WSServiceExtended();
srv.Proxy = new System.Net.WebProxy();
ServeurWSI wsi = new ServeurWSI();
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
wsr = srv.login(wsi);
The service is called 'Extended' because I overrided the auto-generated one in order to add Cookie managment since I am using the Compact Framework. Following the sample in this thread:
https://social.msdn.microsoft.com/Forums/en-US/34d88228-0b68-4fda-a8cd-58efe6b47958/no-cookies-sessionstate-in-compact-framework?forum=vssmartdevicesvbcs
EDIT:
I made some new tests with the Web references and got it to work.
When I add the Web Reference, I have to put some Url to the Web Service. When I set it with the actual hostname instead of the 'localhost' everything is fine.
But then, since I set it manually to the real address just before the call, it shouldn't matter
srv.Url = "http://myServerName:8087/myServerApp/services/myService";
EDIT2:
I might have forgotten some specifics about my environnement.
The Web Services are exposed on my computer on some Tomcat Server.
The application I am working on is also developped on this computer (That's why I can add Web References by putting 'localhost' in the address)
The application is then deployed on a distant device (Windows CE) that will make calls the Web Services through WIFI (There, localhost wouldn't work then)
I tried calling the Web services from other computers successfully.
I'm beginning to think that there might be some differential between the called Url and the one that is set, otherwise, how would I have a difference in behaviour such as the one described in the first edit?
EDIT3:
Well..Seems like it's not a network issue but a .Net compact framework (usage?) issue...
The Url property of the Web Service implementation is simply ignored and the one in the Reference.cs is used in place.
If someone had some idea on how I could troubleshot this, I would really appreciate it.
That error means that you reached a server and the server said "no way". So you're either hitting the wrong server or the wrong port.
I find the telnet client is useful for testing stuff like this. From the command line, you can do:
telnet [servername] [port]
So something like:
telnet myServerName 8087
If it goes to a blank screen, then it connected successfully. If it does not connect, it'll tell you.
The telnet client is no longer installed by default in Windows 7+, so you'll have to install it. See here for instructions: https://technet.microsoft.com/en-ca/library/cc771275
If the connection does open, you could paste in an actual HTTP request to see what happens. A simple GET would look something like this:
GET /myServerApp/services/myService HTTP/1.1
Host: myServerName:8087
One reason for this error can be that the service binds to only a certain IP address. It could well be that the service only listens on the IP that is assigned to the host name, but not on the localhost IP (127.0.0.1).
For example:
If the host myServerName has the public IP 192.168.0.1, your service can choose to listen on all IPs assigned to the host (sometimes specifying 0.0.0.0), or it can specifically listen on 192.168.0.1 only. In that case you will not be able to connect through 127.0.0.1, because the service simply doesn't listen on that IP.
You can "use" this inverse of this feature to make a service accessible only to local clients, not on the public IP-Address, by listening on 127.0.0.1 only, but not on the public IP. This is sometimes used on Linux for example to make MySQL only accessible on the host itself.
I was starting to forget this post but I finally found the problem that was messing things up and it has nothing to do with programmation.
I was doing the calls while the device was connected to the computer via the 'Windows Mobile Device Center' allowing to access the device from Windows.
While connected, the host provided is ignored and all calls on the specified port are handled by the connected computer.
Disconnecting the device allows to communicate properly...

SignalR client won't connect using OWIN Self Host in Azure Worker Role

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!

IIS8 There was no endpoint listening at net.tcp:

i have a WCF service host in IIS8 and I want to use a net.tcp binding.
I have this configuration:
Web.config:
<service behaviorConfiguration="MyBehavior"
name="DecryptService.EmailCenterDecryptTCP">
<host>
<baseAddresses>
<add baseAddress="net.tcp://XX.XX.XX.XX:808/VirtualFolder/Service.svc" />
</baseAddresses>
</host>
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="portSharingBinding"
name="MyServiceEndpoint"
contract="ServiceNamespace.IService">
</endpoint>
<endpoint address="mextcp"
binding="mexHttpBinding"
bindingConfiguration=""
name="MyServiceMexTcpBidingEndpoint"
contract="IMetadataExchange" />
</service>
When I try to consume the service in the same machine as IIS8 with the following configuration works fine:
<client>
<endpoint address="net.tcp://YY.YY.YY.YY:808/VirtualFolder/Service.svc"
binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
contract="ServiceReference1.IService" name="MyServiceEndpoint" />
</client>
YY.YY.YY.YY is the local IP of machine but when I try to consume the service in another machine changing YY.YY.YY.YY to external IP of the machine (ZZ.ZZ.ZZ.ZZ) that runs IIS8 I get the following error:
There was no endpoint listening at net.tcp://ZZ.ZZ.ZZ.ZZ/VirtualFolder/Service.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
Any Ideas?
Thanks and sorry for my bad English
EDIT:
I made a console application running a ServiceHost replacing IIS and with this configuration it works over internet
var svh = new ServiceHost(typeof (Service));
svh.AddServiceEndpoint(typeof (ServiceNamespace.IService), new NetTcpBinding(SecurityMode.None), "net.tcp://serverLocalIp:808");
svh.Open();
Console.WriteLine("SERVER - Running...");
stopFlag.WaitOne();
Console.WriteLine("SERVER - Shutting down...");
svh.Close();
Console.WriteLine("SERVER - Shut down!");
Any idea whats wrong with IIS running the same service over internet? locally works.
Thanks
You also need to setup IIS to receive a Net.TCP connection.
Under Advanced Settings of your IIS Application, then under Enabled Protocols make sure you have http,net.tcp note that there is no space, if you have a space it will fail.
http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx
If you started receiving this error out of the blue one day, it is related to another process hijacking the net.tcp port. In my case it was port 808. Here is how I figured it out after about 3 days--ya this is what I do nowadays, Google and try to figure out other people's fups instead of doing my own work.
Anyhow:
Net.TCP depends on 2 windows services to be running. Go to services and find Net.Tcp Listener Adapter and Net.Tcp Port Sharing Service. If you do not see them, then this answer does not apply to you. It means you have not activated the feature in control panel Turn Windows feature on or off. You will find plenty info on what to enable online.
Stop the the Net.Tcp Port Sharing Service and click Yes in the Stop Other Services popup.
Restart both services.
Open Event Viewer > Windows Logs > System and see if you see any error for SMSvcHost 4.0.0.0 (your version may differ) in the Source column. I had this error: An error occurred in the Activation Service 'NetTcpActivator' of the protocol 'net.tcp' while trying to listen for the site '1', thus the protocol is disabled for the site temporarily. Yes, thanks MS! You started a service but did not really start it and simply added a message to the Event Viewer? Great! Because telling me during the windows service start is too hard, correct? Ok again, anyways, let's keep going.
Then I needed to figure out what is using the port as per error in 4 above. So I ran the following commands (You may need to start the command prompt in admin mode.)
Run netstat -ano | findstr "808" and note the numbers in last the column. Those are process IDs using the port.
Run tasklist /fi "pid eq 9", where 9 would be the process ID from above step.
Now that you know the process name that is using the port, you need to Google and find out what the process is for. In my case it was a related to Intel graphics driver using port 808: OneApp.IGCC.WinService.exe.
That makes sense because some other process was already using port 808 so it wasn't available for Net.TCP.
I had 2 options at this point:
Disable that process
Perhaps see if I can change the port for it.
Luckily they have an update for the driver already so I simply downloaded it and installed it from here.
Reboot then ran the following commands again to ensure the port is free for net.tcp:
Run netstat -ano | findstr "808" and note the numbers in the last column. Those are process IDs using the port.
Run tasklist /fi "pid eq 9", where 9 would be the process ID from above step. Now you should see SMSvcHost.exe which is what we want.
Simple answer, change port number under IIS -> edit bindings -> net.tcp to something else. I changed it to 12345 and this solved my problem.
This is issue related to another process using default port 808 as explained in post above.
If this doesn't help, check answer above and fallow procedure.

Categories