Is there Any way of hosting WCF service on Linux.
I read about wine but i didn't see any example of hosting WCF service with it.
P.S : I have tried mono and mod_mono but to no avail.
You can host it in a stand-alone console application like so:
using System;
using System.ServiceModel;
using Service;
namespace Host
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("WCF Host!");
var binding = new BasicHttpBinding ();
var address = new Uri ("http://localhost:8080");
var host = new ServiceHost (typeof(GreeterWcfService));
host.AddServiceEndpoint (
typeof(IGreeterWcfService), binding, address);
host.Open ();
Console.WriteLine ("Type [Enter] to stop...");
Console.ReadLine ();
host.Close ();
}
}
}
Where GreeterWcfService is the WCF service class itself and IGreeterWcfService is the service contract.
Full working example solution in GitHub - with separate projects for the service, the hosting and a client. Check it out.
Its possible but you should refer to this link for understanding current state and known issues - http://www.mono-project.com/docs/web/wcf/. It's limited now. For eg. if you wish to use WSHttpBinding its not supported currently.
Related
I just started playing with Ninject for self hosted WCF services.
I ran into a problem where it isnt generating a wsdl (url?wsdl or url?singleWsdl).
I start up the service with this :
private static void StartNinjectSelfHost()
{
var someWcfService = NinjectWcfConfiguration.Create<CalculatorService, NinjectWebServiceSelfHostFactory>();
_selfHost = new NinjectSelfHostBootstrapper(CreateKernel,someWcfService);
_selfHost.Start();
}
If I revert to the standard way with this:
private static void LoadWcf()
{
if (serviceHost != null)
{
serviceHost.Close();
}
// Create a ServiceHost for the CalculatorService type and
// provide the base address.
serviceHost = new ServiceHost(typeof(CalculatorService));
// Open the ServiceHostBase to create listeners and start
// listening for messages.
serviceHost.Open();
}
Then I get the wsdl just fine at this URL:
http://localhost:8000/ServiceModelSamples/service?singleWsdl
I'm guessing I have to tell Ninject to do this, but I'm struggling to find any good info by searching.
Any help on enabling the wsdl is appreciated.
Nevermind I'm dumb. I wanted to use "NinjectServiceSelfHostFactory" instead, now it works
I am using Dynamic IIS Hosting (http://blog.micic.ch/net/dynamic-iis-hosted-wcf-service) with http binding. How can I use tcpbinding with dynamic IIS hosting.
Thanks
If you are experiencing problems with registration VirtualPathProvider on start up using non-HTTP activation, you should put class with any name to App_Code folder. This class must have public static void AppInitialize() method, where you can register VirtualPathProvider.
namespace YourHostNameSpace.App_Code
{
public class NonHttpActivation
{
public static void AppInitialize()
{
//do start up stuff here
}
}
}
By the way, WCF 4 provides file-less functionality out of the box on top WCF 4 Routing.
While trying to build a client-server WCF application in Mono we ran into some issues.
Reducing it to just a bare example we found that the service only accepts one client at a time. If another client attempts to connect, it hangs until the first one disconnects.
Simply changing to BasicHttpBinding fixes it but we need NetTcpBinding for duplex communication. Also the problem does not appear if compiled under MS .NET.
EDIT: I doubt (and hope not) that Mono doesn't support what I'm trying to do. Mono code usually throws NotImplementedExceptions in such cases as far as I noticed. I am using Mono v2.6.4
This is how the service is opened in our basic scenario:
public static void Main (string[] args)
{
var binding = new NetTcpBinding ();
binding.Security.Mode = SecurityMode.None;
var address = new Uri ("net.tcp://localhost:8080");
var host = new ServiceHost (typeof(Hello));
host.AddServiceEndpoint (typeof(IHello), binding, address);
ServiceThrottlingBehavior behavior = new ServiceThrottlingBehavior ()
{
MaxConcurrentCalls = 100,
MaxConcurrentSessions = 100,
MaxConcurrentInstances = 100
};
host.Description.Behaviors.Add (behavior);
host.Open ();
Console.ReadLine ();
host.Close ();
}
The client channel is obtained like this:
var binding = new NetTcpBinding ();
binding.Security.Mode = SecurityMode.None;
var address = new EndpointAddress ("net.tcp://localhost:8080/");
var client = new ChannelFactory<IHello> (binding, address).CreateChannel ();
As far as I know this is a Simplex connection, isn't it?
The contract is simply:
[ServiceContract]
public interface IHello
{
[OperationContract]
string Greet (string name);
}
Service implementation has no ServiceModel tags or attributes.
I'll update with details as required.
I've played around with this a bit, and it definitely looks like a Mono bug.
I'm porting a WCF application to run in Mono at the moment. I had played with some NetTcpBinding stuff, but I hadn't tried this scenario (multiple connections to a Mono-hosted service host). However now I try it out, I'm able to reproduce - both in 2.6 and the latest daily package.
It does work in .NET, however. Any difference in behavior between Mono and .NET is classed as a bug. You should log it on Bugzilla with a test case, I would also post in the Mono newslist.
Good luck.
Definately a bug. I'm wondering if there was a version it was working correctly...
I've posted it at Novell Bugzilla, if you are interested in its progress.
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using BankServiceClient.BankServiceReference;
namespace BankServiceClient
{
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8000/Simple");
Type instanceType = typeof(BankServiceReference.BankClient);
ServiceHost host = new ServiceHost(instanceType,baseAddress);
using (host)
{
Type contractType = typeof(BankServiceReference.IBank);
string relativeAddress = "BankService";
host.AddServiceEndpoint(contractType, new BasicHttpBinding(), relativeAddress);
host.Open();
Console.WriteLine("Press <ENTER> to quit.");
Console.ReadLine();
host.Close();
}
/*
* Consuming a WCF Service and using its method.
*/
//IBank proxy = new BankClient();
//double number = proxy.GetBalance(1234);
//Console.WriteLine(number.ToString());
//Console.ReadLine();
}
}
}
First, a couple of questions:
The 'baseAddress' attribute, what exactly is it? When I launched my service using the default F5 (no console application) the service launched on a random port on localHost. How can I write in an exact number and expect it to go there? Confused at this one.
What is the relativeAddress attribute? It says BankService but what should I write in that attribute? Confused at this one as well.
Here's the exact error message I get when I try to run this Console application:
HTTP could not register URL
http://+:8000/Simple/. Your process
does not have access rights to this
namespace (see
http://go.microsoft.com/fwlink/?LinkId=70353
for details).
First is your client project set to be the start up project?
And to answer your questions.
1) baseAddress (URI Class) is the base address for your hosted service. I am thinking you are launching some other project.
2) You have two options on configuring endpoints(reference). Relative and Absolute. The way you did it will take your base and appends your relative -> http://localhost:8000/Simple/BankService
Lastly to fix your hosting issue see this SO link:
WCF ServiceHost access rights
How do I host my WCF class library in a console app? I have a WCF service within a class library and I wanted to test the service outside my project with a test app.(I have to do it outside the project)
Create a simple console app, add a reference to your WCF service assembly, and then basically write these few lines:
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Namespace.YourWCFService)))
{
host.Open();
Console.WriteLine("Service host running......");
foreach (ServiceEndpoint sep in host.Description.Endpoints)
{
Console.WriteLine(" endpoint {0} ({1})",
sep.Address, sep.Binding.Name);
}
Console.ReadLine();
host.Close();
}
}
All you do is instatiate a ServiceHost and pass it the type of a service (implementation) class, and then basically call .Open() on it.
The Console.ReadLine() just wait until someone presses ENTER and then terminates the service host.
That's all there is! (of course, you need to specify service address and bindings in a app.config for the service host console app for it to work)
You may create ServiceHost in your console application with your existing service contract (from your class library).
After the service is running, your test project can access your WCF Service as usual.
Consider using the WCF Service Host application: http://msdn.microsoft.com/en-us/library/bb552363.aspx
You can simply point the host to your service class library and configuration file and it will host your service for you.