I was wondering if anyone could help - I have a local network (wireless, my computer and a laptop connected to it) and I've tried hosting a rest service developed with ServiceStack on it. If I run the application on the computer (a console app for now) and try to access the service using the machine IP or 127.0.0.1 it works fine - but if I try and access it from the laptop, using the computer's IP it simply stalls, and the REST service is never called.
I've tried turning off all firewalls etc, running everything in Admin mode but still nothing.. am I missing something simple to get this working?
Any help is much appreciated!
Some of the code samples (My AppHost class is inheriting from the AppHostHttpListenerBase)
restServiceToStart.Value.Init ();
restServiceToStart.Value.Start (_HostUri);
where for my main machine, the _HostUri is set to "http://my-ip-address:8080/"
You haven't listed the code you use to start your AppHost (please be descriptive when asking questions) so I'm going to assume you're not listening to http://*:{port}/, e.g. from the Self Hosting wiki:
var appHost = new AppHost();
appHost.Init();
appHost.Start("http://*:1337/");
The * wildcard says to listen on every local network interface.
Related
I am running Visual Studio in a VMWare Fusion virtual machine. When I debug my application, VS makes the application available on localhost:50609. I can use it effectively while in the vm itself. However, I would like to access this running instance from a simulated mobile app running in the host machine (an OsX host). This does not work -- the host simply does not see the running instance on the guest.
I started thinking this had something to do with firewalls or the way that the VM networking was set up. But, long story short, I'm pretty sure that the web application is hosted specifically on "localhost", and therefore is inaccessible outside of the localhost itself. Thus, I cannot use the guest OS's IP address on the virtual network to access the site. That is actually true even within the guest OS; i.e., I cannot access the site by using address 192.168.x.x:50609, but I can access it using localhost:50609 (again, this is from the guest, not the host).
So, I am convinced that VS or IIS (I think it's running IIS Express; whatever comes by default with VS 2013) is set up to only allow connections through localhost. That seems like a very good default for security reasons, but in this instance it's not what I want to do.
Can I make this debugged application accessible to an outside machine?
The fact that this is running using VMs is probably quite irrelevant, but I just wanted to give the specific setup. I've disabled Firewalls to test this, so it's not something like that.
[EDIT] The link pointing to how to do this in Web Matrix is useful, but I still lack the final step for how to change the default address in Visual Studio. I think it's only half the answer.
I struggled with this for two days and scoured the interwebs, following several "red herring" leads.
On MY system I finally got it working as expected. The key is that Vagrant (Docker) will not properly forward on 127.0.0.1. You need to set the server to listen on '0.0.0.0'. I knew that from my work with Rails in Vagrant. But it was not easy uncovering HOW to specify this in the DotNet CLI (IIS).
The answer is that you either add this to the call to WebHostBuilder in 'Program.cs' of your project:
.UseUrls("http://0.0.0.0:5000") // Take that, Docker port forwarding!!!
OR call the DotNet CLI like this:
ASPNETCORE_URLS="https://*:5000" dotnet run
I settled on a third option. I set an environment variable:
ASPNETCORE_URLS="https://*:5000"
I have a client where I'm trying to port their code to my machine for development purposes. They built their wcf services using classes and interfaces only - thus no svc files. Almost like you would find with self hosting.
When I run the application, these services are hosted by WcfSvcClient (for debugging purposes) and I can see them starting up. I can however not access these services by pointing my browser to the given urls, nor can I step into that code.
I know this should work, because it works on a client machine - but I cannot tell why it isn't working on my machine other than suspecting it needs a computer which runs on their domain?
The strange thing I've noticed is they declared a host url in the wcf services config file for each service. This url is used when starting WcfSvcClient - but it is not configured anywhere else I can see i.e. not IIS. It just mysteriously exists and I have no idea how to call it, debug it or even under which account it runs. Is this configurable somewhere?
Could someone perhaps point me in the right direction? My knowledge with wcf is very limited. Thanks
Ok so it seems wsHttpBinding does support authentication where the domain the service is running on is relevant. This is it's default behavior. You have to explicitly tell it to not do so, by including:
securityMode=None
in your binding configuration. Not suggested for production.
For more information see this post: WCF slow ServiceHost.Open() call
I have been through WCF and related topics, created my first WCF service. It works fine but the problem is that I don't understand hosting concept.
Different tutorials do different things like some create separate console applications for it to host service then using it in Asp.net app but some doesn't host it in any place and just add reference to another project and use it.
I don't understand that when to host where and why?
Please help me in this issue. I am using Visual studio 2013 with .net 4 and asp.net c#.
Basically, a WCF service needs to be hosted somewhere, so that it can be accessed from somewhere else. There are several ways to do this (and probably more than I know about too), but two of the most simple and common ways are to host the service in IIS Express, or in IIS (Internet Information Server).
IIS Express
The simplest way to achieve the first (IIS Express), is to simply right click the project in Visual Studio, and select View in Browser. That will open a directory listing in your browser, and in that directory you should see a file ending in .svc. Clicking that file should open the service description page with text like:
You have created a service.
To test this service, you will need to create a client (...)
The URL to that page, is in effect the URL clients will need to connect to your service. It should look something like http://localhost:64835/YourServiceName.svc.
That means the service is hosted locally, at port 64835, and accessible for clients at that address. Since this is in IIS Express however, it will no longer be accessible once you've closed Visual Studio, since it only runs as part of it.
IIS proper
Hosting in IIS means your service will be accessible whenever IIS is running. Once installed, it will usually start up when you log in, and run silently in the background. When it is running, you can start your service simply by accessing the correct URL. If it is not running, it might take a few seconds to start it. The next time it is called, it should respond quickly.
Note that in IIS, an application will by default run on port 80, which is the default port checked by browsers and possibly other clients - which means you don't need to specify it as in the example above. The URL will therefor generally be something more simple, like http://localhost/yourservice/yourservice.svc (although you could configure it to another port, or another protocol (say https://.., or something else if you like).
Once configured, and the relevant port is open however, your service should be accessible to the rest of the world.
Note: From the outside world, the URL will be different; it could be something like:
http://123.456.789.123/yourservice/yourservice.svc, if that is your IP address, or
http://yourdomain.com/yourservice/yourservice.svc if you've set up a domain.
I would suggest you consider hosting under two categories:
Self Hosting
IIS Hosting
As per you question "when to host where and why", I would say that you self host a WCF service only during testing. Mostly, self hosting is not used in live/production environments. For production environments use ISS hosting.
Self-hosting would be useful for testing on the local machine and on the intranet, while IIS hosting would be useful over the internet.
However, one must be aware that there is no rule as such regarding the usage of a particular hosting technique in any particular situation. With experience, the developer will be the best judge.
I have one WCF service deployed in multiple websites hosted in IIS7 and sometimes (development environemnt) in VS2010.
Often multiple instances are connected to the same database and usually its not a problem as its read-only access, but sometimes (like in logging) I need to uniquely identify instance of the service accessing DB.
Currently I do it by putting special attribute in web.config which I'll later use as a part of primary key, but I do feel its not ideal solution.
I thought about site-name in case its hosted in IIS and machine name + port if its hosted from VS2010.
And here comes the question: How to access info about where the WCF service is deployed and how to do it programmatically from inside of deployed service in c#? Is it at all possible?
Thank you for your suggestions.
Michal
The other day there was a question about how to get the IP address of the WCF server, for logging. This topic might help: How to get IP address of WCF web service
You could also determine if you are running in IIS by finding out what process your app is being run from using System.Diagnostics.Process.GetCurrentProcess(), and see if it is "w3svc.exe", which is what the IIS app pool runs as.
If I understand your question correctly, and I may not, you would like to know were on the server the actual instance is deployed.
If this is the case you can use something like:
(string)AppDomain.CurrentDomain.GetData("APPBASE")
Or I believe this will also work:
AppDomain.CurrentDomain.BaseDirectory;
Using reflection on the assembly or process itself will not work because the running process is the host (IIS, IISExpress, etc), but the two methods I specified should give you the location of the service itself for hosted apps.
I need to change some configuration settings on-the-fly in a Windows Azure project - and they need to be changed via a web service call (updating the application's configuration either via the platform api or the Azure Management site isn't an option here).
The project has multiple web and worker roles - all of which will need to know about the new configuration when it is changed.
The configuration is persisted to durable storage, and it's also cached during runtime in a static variable.
My solution was to create an internal (tcp) endpoint on my roles, and use that to loop through all of the roles and instances within those roles, create a client on the fly, and tell the instance about the new setting. (pretty much identical to: http://msdn.microsoft.com/en-us/gg457891)
At first I started a ServiceHost in the WebRole's RoleEntryPoint... and I was confused why everything seemed to be working fine when I stepped through the communications (the static variables where getting set correctly) - yet when I'd make other webservice calls, the static variable seemed to have "forgotten" what I set it to.
This was the case both locally, and in the Azure staging environment.
At this point I realized that because we're using full-IIS mode, the RoleEntryPoint and the Web Services were running in two separate processes - one in Azure's stub, and one in IIS.
"Not a problem" I said, I'll simply move the line of code which starts the ServiceHost from my RoleEntryPoint into the global.asax - at which point the ServiceHost will have been started in the same process as the rest of the site - and the static variables would be the same ones.
Here's where I'm having a problem; This works great on my local machine running in the dev environment. As soon as I deploy to staging I start getting error emails saying the channel used to connect to the service can't be closed because it's in a "faulted state".
Question:
What's different about Azure vs. Dev environment that is causing this?
How can I fix or workaround the problem?
Does anyone have any general advice on how I should go about obtaining a more descriptive error... do I have to enable full wcf diagnostics in Azure to get this, or is there some other way I can get at the exception details?
Follow-Up:
Via remote desktop i've learned several interesting things:
Non-HTTP Activation isn't installed by default on Azure WebRoles. I believe this can be overcome via a startup script:
start /w pkgmgr /iu:WCF-NonHTTP-Activation;
The website created in IIS by the web role doesn't have the net.tcp protocol enabled by default. I also believe this can be overcome with a startup script:
%systemroot%\system32\inetsrv\appcmd.exe set app "Website Name Here" /enabledProtocols:https,http,net.tcp
I haven't had time to take this all the way, as deadlines have forced me to implement some workarounds temporarily.
Some useful links related to this topic:
http://msdn.microsoft.com/en-us/magazine/cc163357.aspx
http://forums.iis.net/t/1160443.aspx
http://msdn.microsoft.com/en-us/library/ms731053.aspx
http://labs.episerver.com/en/Blogs/Paul-Smith/Dates/2008/6/Hosting-non-HTTP-based-WCF-applications-in-IIS7/
UPDATE (6/27/2011):
Amazingly, someone at Microsoft (whose blog I commented on) actually got me an answer on this.
The Azure & WCF teams updated this post:
http://blogs.msdn.com/b/windowsazure/archive/2011/06/27/hosting-services-with-was-and-iis-on-windows-azure.aspx
The link contains all of the information you need to get going with this.
And a HUGE thanks goes to Yavor Georgiev, the MSFT PM with the win.
It's been quite a while since I've asked the question, and no answers, so let me leave this:
Per my follow-ups in the post, there are ways of making this work... but they are complicated and difficult to implement.
For WORKER ROLES, netTcpBinding works perfectly. No issues here. Go ahead and use it.
For WEB ROLES, you've got problems.But netTcpBinding is what you need to use for exposing internal endpoints. What to do?
Well, here's what I did:
Start netTcpBinding service in your RoleEntryPoint using ServiceHost.
Create standard WCF service in your web role using SOAP / JSON / Whatever you want.
When you receive requests through your netTcpBinding, proxy them along to the WCF service on the loopback adapter.
Properly secure your "internal" WCF service with SSL client certs.
It's not perfect... but it works, and it's not terrible.
I suspect that needing to do this kind of thing isn't super common, and I really can't think of any reason why you'd need to other than to dynamically modify settings at runtime... which means you're not slamming these services like crazy.
Obviously, YMMV.
I had a miserable time getting HTTP working between instances in staging, and gave up when it looked like I needed to mess around with netsh to give my processes permission to listen via an HttpListener (sheesh!). So I switched to TCP via sockets. HTTP just adds overhead in a point-to-point communication scenario like this.