What technologies are used / recommended for HTTP Rpc Calls from Silverlight. My Server Side stack is JBoss (servlets / json_rpc [jabsorb]), and we have a ton of business logic (object creation, validation, persistence, server side events) in place that I still want to take advantage of.
This is our first attempt at bringing an applet style ria to our product, and ideally we keep both HTML and Silverlight versions.
For better or worse the powers that be have pushed us down the silverlight path, and while flex / java fx / silverlight is an interesting debate, that question is removed from the equation. We just have to find a way to get silverlight to behave with our classes.
Should I be defining .NET Class representation of our JSON objects and the methodology to serialize / deserialize access to those objects? IE "blah.com/dispenseRpc?servlet=xxxx&p1=blah&p2=blahblah creating functions that invoke the web request and convert the incomming response string to objects?
Another way would be to reverse engineer the .NET wcf(or whatever) communications and implement the handler on the Java side that invokes the correct server side code and returns what .NET expects back. But that sounds much trickier.
T
Well since we are using JSON Rpc over HTTP on the server -> HTML clients, we decided to use HTTP calls and the .NET JsonSerializer; future plans are to add Java Annotations on our EJB project and a console applciation that will run against the EJB and generate the HTTP calls and F# Records with the DataContract attributes.
It is working pretty smoothly. Had some issues with async in silverlight, but got it working with some aid from the folks at MS.
Thx
Related
I am working on a project requiring communication between the Presentation layer (MVVM based client) and the Business layer. The application is to be installed on a single machine, and as such could have been executed using a .net remoting based approach. However, I have been suggested to use WCF since .net remoting is deprecated and WCF is the way to go.
So I implemented WCF Service as a WCF library project. I added a service reference (using visual studio tool by discovering services in the solution), which was successfully added on the client side. All works well, since during debug session visual studio launches the service library and the client can connect to it successfully.
Now Since the client and service host will be installed on same machine, I was thinking of using named pipes transport and self hosting for the WCF service. Here is where this gets very confusing to me:-
Since the MVVM client is the "main" app (since it is the application frontend), the client will be launched first. I am unable to come up with a solution to launch the service host "on-demand" when the client needs the same.
What are the solution I can use to do what I require for 1? I am not sure of using a continuous service through windows service for something that will be required "on-demand".
Please suggest clean approach to implement a way to launch "on-demand" service.
Thanks in advance.
I'm not quite following you here. MVVM is cake and really doesn't have anything to do with your problem. Using a servicebased architecture is a must today, I just want to smack every old guy/gal sticking to direct SQL on the client side, and don't see the dangers with that.
Well anyhow, you may solve this different ways. WCF is BIG, to big in my opinion. One way to use it, common on small applications like apps(WP8.1, 8.1 apps++), is just to connect, call the method you need and the close the connection. Case solved, given that I understand your needs. The otherway is to keep the session alive for each service... (ugh, loadbalancing etc).
I've been working on large LOB applications the last 4 years my self, what I can tell, is that if I were in charge, I would have done it very differently. For once I would used JSON endpoints with SSL over HTTP, and the json.net serializer. The datacontract serializer which is the default in WCF, is not good news at all. JSON allows easy communication with JavaScript based applications, and the serializer doesn't break like porcelain as the datacontract serializer does. Address/baseaddress may be stored in your config file, so it may be changed upon deployment(you probably have many servers, for different environments).
This is a really old post covering the subject(supporting SOAP aside JSON); REST / SOAP endpoints for a WCF service
Don't be stupid and just call your services directly now! Use the interface(Wrap if necessary) and feed it to your viewmodels for proper TDD! It will also allow you to completely replace WCF with another form of communication.
There also are alternatives to WCF.
IIS? Hosting WCF in IIS rather than a proper service? No way, flush that idea down the waterloo ;) (internal joke)
EDIT:
BTW: Your service must ofc already be running for your client to connect to it! Or nothing will be listening to your configured port. If you are selfhosting, you can use parameters to start in debug mode, that is start your service like a regular application you may debug. In Program.cs;
if (args.Length > 0 && String.Equals(args[0],"debugmode", StringComparison.OrdinalIgnoreCase)
{
Service1.Create(); // Debugging!
}
else
{
// Hosting
service = new Service1{ServiceName="YourService"};
ServiceBase.Run(new ServiceBase[] {service};);
}
Hope it helps,
Cheers,
Stian
We are developing a WCF REST service which will be consumed by a desktop WPF application and will also be a source of data for the ASP MVC4 website.
So far I've run into countless technical issues and most importantly I am worried about the future of the Microsoft.OData.EntityFrameworkProvider. (Please check blog comments here).
The issues include:
There is no easy way (without using DTO) to add properties on the service entities which will be passed through OData but won't be stored in the database Actually there is an easy way:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.ComplexType<CustomType>();
}
There is no easy way (without parsing XML or using DTO) to store properties on client entities without them being sent to the service (v5.6.0). The "hard" way is to hook into RequestPipeline and ResponsePipeline:
Configurations.ResponsePipeline.OnEntryEnded(OnReadingEntry);
Configurations.RequestPipeline.OnEntryEnding(OnWritingEntry);
using DTO is cumbersome to say at least, automapper helps with retrieving of IQueryable results but updating entities requires full implementation of IUpdateable, which actually works on DTO but is required to update entities so implementation of it is very tricky if even possible (I searched for existing solutions and these mostly cover in memory data source so I implemented a working solution but without links, I can dig it from source control if anybody is interested). Tested on v5.6.0.
Client entity containing dynamic field will crash when retrieved from a service (checked on 5.6.1)
accessing DbContext from EntityFrameworkDataServiceProvider requires a hack
This package has not been updated for almost half a year and this fact itself is very worrying.
My question is what Microsoft or open source alternatives to Microsoft.OData.EntityFrameworkProvider link between EF context and a client are suitable to replace this supposedly dead library? The critical requirement for such a link would be to have a tracking client-side context and entity framework 5 or 6 compatible service.
Is Microsoft.AspNet.WebApi.OData a good solution also for desktop applications?
Are there any other Microsoft or open source projects have similar capabilities?
For WCFDS update, you can refer to Future Direction of WCF DS service.
In the issues you listed, I am sure that issue 1 can be easily resolved in web api by tag [IgnoreDataMember], here.
For Issue 2 and 4, one suggestion is you can add a data layer in client, which can handle extra data model and dynamic field
Just a couple of thoughts...REST is not the same as OData...so your question is confusing. If you meant WCF Data Services, then definitely go with the new WebApi. As Maya's link shows, The WCF DS team announced they are basically done.
However, your client is usually agnostic of what technology you are using for odata and its data layer...its a disconnected architecture. So if you have a mapping impedence on the server side, that is one issue, but which client is consuming the odata ought to be irrelevant. But likely I did not understand your stated problem correctly...Do you mean that you own both the client and server and want to share the entity class definitions? If you are that tightly coupled, you can add service resources customized for the client, and others customized for your MVC app.
For some practical workaround, WCF DS offers query interceptors, that let you manipulate outgoing data. The new WebApi is basically works from controllers and gives you full control over intercepting the requests and manipulating what needs to be done with the data.
Finally, just a suggestion for your desktop client...Lightswitch works wonders with oData...point and click...it generates your proxy and client model on the fly and gives you huge control over the client and what it does with the responses from the server.
I am working with a native C client application (not built with Visual Studio) that needs to call a WCF service. I am creating the WCF service, so I have complete control of it.
Most of the information I have found deal with calling WCF from unmanaged C++ clients.
Has anyone tried WWSAPI?
I am hoping to get some direction on whether this is even possible and what technologies can be used. Any help would be greatly appreciated!
you can use gSOAP is a technology that allows you to create stubs for client and server side code from WSDLs. Here is step by step tuttorial and that one for windows
WCF is very powerful and configurable and allows to use many different bindings (HTTP, Sockets, MSMQ, custom, etc.). Starting from version 3.5 I belive, you can use a JSON/REST bindings and contracts. Here is an official link about this: Overview of REST in WCF, and some samples here: WCF 4 JSON REST Service and here: REST Service with WCF and JSON.
Now, why REST and JSON? because these prococols are very lightweight and do not need huge dependencies or libraries. That was in fact the whole point of REST, as opposed to SOAP.
So, with these, you only need a TCP/HTTP stack and a JSON parser on the client-side wich makes it relatively easy to program in C. Here is a link to a simple JSON library: Jansson
Currently I have a working Silverlight application that uses .Net RIA Services.
It's structure:
Client-side
Application.Client.UI.dll (Xamls and
basic UI stuff)
Application.Client.BL.dll (Contains the Link to RIA and most of the business logic)
Server-side
Application.Server.Data.dll (Server-side dll that holds the Entity-model and it's generated domain service)
Application.Server.Web.dll (Only the ASP.net hosting container, which references the
Application.Server.Data.dll)
I placed most of the business logic on the client side (Application.Client.BL.dll) for better user-experience (fast reactions) and to free up server resources. My challenge is now to re-use this client-side dll including it's RIA data access capabilities, in a server-side windows service. I'm wondering, is that possible at all? Is the Application.Client.BL.dll still able to consume the existing RIA service, or does that dll require the Silverlight runtime to identify/locate it's service target, and therefore will not work anywhere else.
Curious for your answers
You really shouldn't put any business logic on the client, the guys in security and / or architecture will hate you for it ;-). Furthermore you can't use Silverlight assemblies in ASP.Net or Desktop projects and vice versa. If memory serves correctly, Silverlight uses an entirely different CLR altogether.
I encountered similar needs when working with compact framework assemblies I also wanted to compile for the full framework. I'll describe how I would work around this scenario.
If there exist any issues referencing the Silverlight assembly, consider building two projects as follows:
Project #1 would be your Silverlight library, and should contain all the source files you want to use on the client.
Project #2 would be your Windows Service. Instead of including source files directly, use the "Add Existing Item", find the original source file in project #1, then (and this is the magic), drop down the Add button to choose, instead, choose "Add as Link".
By including the source file as a link, you retain the ability to maintain your source code in one location, but add the ability to compile your code for multiple frameworks. As long as the code relies on assemblies available in both the Silverlight framework and the full .NET framework, then you're money.
Now, regardless of whether you choose a multi-project approach, know that domain context classes have additional constructors that allow you to specify contextual information, such as the URL, for the corresponding domain service. I use the following code in one application to construct a domain context for a domain service that provides personnel data:
var context = new PersonnelDomainContext(
new Uri(ConfigurationManager.AppSettings["PersonnelServiceUrl"]))
In this case, the URL looks something like:
http://website-url/Services/Hyphenated-Namespace-PersonnelDomainService.svc
Of course, when writing a Windows Service, nothing is stopping you from referencing the server-side domain service (not context) assembly directly. With the domain service in hand, you can instantiate a service instance without all the additional configuration and without the additional network XML payload. There are trade-offs to this approach, such as forfeiting centralized configuration management (such as connection strings), but depending on your circumstances, you may find the trade-offs to be worth it.
Happy coding!
Have you considered using fork-reuse? Take a look at:
http://sharednow.blogspot.com/2011/05/its-not-just-reuse.html
I am creating a Silverlight 2 user interface to a remote instrument. There are two concurrent users at different sites interacting with the instrument (operator at the instrument and remote scientist) and any number of observer users not interacting with it, just watching. However, whenever one of the two active users changes something these changes must be immediately reflected in the UIs of all users, e.g. panning or zooming an image or annotating or selecting part of an image, adding items to a collection displayed in a listbox. Within the client I use observable collections which easily reflect changes made by that user, but it is harder seeing changes made by another user. I can poll for changes from each client but something like push notifications would be better. I have extensively Googled for examples but not found anything which is quite what I need. There are all sorts of security issues with Silverlight interacting with WCF services which mean many potential examples just don't work. I have essentially run out of time on this project and need help fast. Does anyone have any suggestion of a suitable simple example which illustrates how to do this? I am an experienced developer but have had to teach myself Silverlight and WCF services and there is noone in my area who knows anything about these. Even tho' I have done a fair amount of ASP.NET work I am not a web/Javascript guru. Thanks.
Push notification is supported in Silverlight 2 using the new WCF PollingDuplexHttpBinding support. There are two assemblies installed with the Silverlight SDK (one for Silverlight app one for WCF server).
I have a few blog posts and a full sample application that demonstrate how to 'push' Stock updates from a Console Application server that self-hosts a WCF service to connected clients. It also shows how each client can add notes against a Stock and have those notes synchronized (pushed from server) to all other connected clients.
The latest version of the sample (Part 4) shows how to synchronize pushed updates between both Silverlight and WPF clients using two server endpoints as follows:
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace StockServer
{
public class StockServiceHost : ServiceHost
{
public StockServiceHost(object singletonInstance, params Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
public StockServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
}
protected override void InitializeRuntime()
{
this.AddServiceEndpoint(
typeof(IPolicyProvider),
new WebHttpBinding(),
new Uri("http://localhost:10201/")).Behaviors.Add(new WebHttpBehavior());
this.AddServiceEndpoint(
typeof(IStockService),
new PollingDuplexHttpBinding(),
new Uri("http://localhost:10201/SilverlightStockService"));
this.AddServiceEndpoint(
typeof(IStockService),
new WSDualHttpBinding(WSDualHttpSecurityMode.None),
new Uri("http://localhost:10201/WpfStockService"));
base.InitializeRuntime();
}
}
}
WPF clients connect to the WSDualHttpBinding endpoint and Silverlight clients connect to the PollingDuplexHttpBinding endpoint of the same WCF service. The app also shows how to handle the Silverlight client access policy requirements.
Clients (Silverlight or WPF) can add notes against a Stock in their UI and these notes propagate back to the server to be pushed to all other clients. This demonstrates communication in either direction and hopefully performs all of the necessary communication required for your app.
You can see a screenshot of the demo application running here.
Not that am pushing Flex in fan boy fashion, but matter of factly this is the kind of architecture we build into all our Flex-based applications routinely. Here is what we do on Flex - no doubt it could be suitably translated to Silverlight:
We take three ingredients and integrate them together to accomplish this capability:
Comet pattern (an HTTP compatible way to do server push notifications - look on Wikipedia for more info)
JMS messaging topics (publish/subscriber queues)
The Adobe BlazeDS servlet
The latter item implements the Comet pattern, supports AMF object marshaling (Adobe's binary serialization format for ActionScript3 objects), and bridges to a JMS queue or topic. When bridging to a topic, then multiple Flex clients running in a browser can be proxied in as subscribers to a JMS topic. So if any client publishes a message (or the server-side code publishes into the topic), all client subscribers will have the message pushed to them via BlazeDS and the Comet Pattern implementation.
Effectively you need to locate or write a component that accomplishes what BlazeDS does. You might also need to implement some client code that interacts with the Comet pattern of this server-side component.
Does WCF support the Comet Pattern and bi-directional messaging? Especially where complies to HTTP and port 80 or port 443 for SSL. Looks like you've already looked into that and not found anything for bi-directional messaging. So you may need to roll your sleeves up and do some coding.
Some things to note about doing server push to a web app:
BlazeDS supports two primary modes of implementing the Comet pattern (there's actually a 3rd polling option but am ignoring it):
long-polling
HTTP streaming
The long-polling one you should find to be more universally supportable to most web browsers. So you might streamline to just supporting that initially. Or you could spend the time to make your client code try HTTP streaming first and switch to long-polling if necessary.
As to a message broker that can provide publish/suscribe capatibility, you might consider using ActiveMQ JMS. It is open source and free with active community support (you can buy support too). Plus you can use NMS to integrate as a .NET client.
Having a message broker sitting in the middle-tier is actually important because it will be a place for messages to be placed safely. If your clients are doing long-polling, you wouldn't want them to miss any new message during an interval when they're not actually connected.
Another thing to consider in high traffic volume scenarios (hundreds or thousands of clients, such as a web site on the Internet), you need to have an approach to the Comet Pattern that is scalable.
In the Flex/Java world, the BlazeDS servlet (which is open source) has been modified to work with asynchronous model. In Java a socket listener can be built to use NIO channels and Java Concurrency Executor thread pools. The Tomcat web server has a NIO listener and support for asynchronous Servlet 3.0 events. BlazeDS in particular has been modified, though, to work with the Jetty web server. The bottom line is that the scalability of this asynchronous approach means a single physical web server can be enhanced to support up to around 20,000 concurrent Comet-style client connections.
It's been a while since I've done serious .NET programming but used to the io capabilities were much like Java 1.1 except with an asynchronous result handler capability. This, though, is not the same thing as creating asynchronous socket listeners via Java NIO channels. A NIO channel implementation can support hundreds to thousands of socket connections with a relatively small thread pool. But C# and .NET has gone through two or three significant revs - perhaps there have been new io capabilities added that are comparable to NIO channels.
I just wanted to clarify that the PollingDuplexHttpBinding doesn't implement 'true' push notifications, as reveals its name (polling). From the msdn documentation:
When configured with this binding, the Silverlight client periodically polls the service on the network layer, and checks for any new messages that the service wants to send on the callback channel. The service queues all messages sent on the client callback channel and delivers them to the client when the client polls the service.
However it is more efficient than the traditional way of polling a web service, since after each poll, the server will keep the channel open for a certain time (say 1 minute), and if a message arrives in that time it will directly 'push' the message to the client. The client has to repeatedly renew its connection, it so to say polls the service.
If you want to implement real push notifications with silverlight I believe you need to work with sockets, and I recommend reading some of Dan Wahlin's blog posts on the subject.
Alternatively,
if you want a native silverlight API with no proxies, bridges or webservers involved you could use Nirvana from my-Channels as your messaging middleware. Check out Nirvana from my-Channels and their showcase site. (sorry i am a new user and cant submit links):
Alex
EDIT: it's actually working fine. I got badly bitten by the "hidden variable" in a closure :(
I used the PollingDuplex for SL2 and I think that it's not ready for production yet.
My main issue is the fact that it doesn't discriminate on the clients on the same machine. If I run 2 clients then one of them won't be able to poll the server anymore and will die of timeout. There is a SessionId that is different for the 2 clients but it's just ignored on the client side.
Likewise, if I kill a client and then create a new one afterwards then the new client will get the push updates from the previous client for a while.
Did anyone encounter the same issues or are they fixed in SL3?
Actually I ran some more demo codes and realised that for some reason you have to specify the InstanceContextMode and InstanceMode so that the service is session based and not a singleton (as far as I can tell). There are clear performance issues in the simple demo code that I pulled.
It is quite unfortunate that this behaviour wasn't documented.
My organization found the Silverlight 2.0/WCF push implementation to be a little "not ready for prime time", at least for what we were planning to use it for.
We ended up going with XMPP/Jabber, because it is a more well formed beast, and you can implement it fairly easily in Silverlight, by just getting some resources off the internet.
I do believe that Silverlight 3.0 will implement a newer/more well formed push implementation, from what I can tell from publicly available information.
The PollingDuplexHttpBinding is probably the most elegant way to do it.
One possilby less involved alternative is to use a TCP socket from your Silverlight client. Whenever one of the Silverlight clients needs to have an update pushed you can send it a TCP message which contains the name of the WCF service it needs to call or some other light weight piece of information.
I use this approach for an application and it works well.
One much simpler and more powerful solution at the site http://www.udaparts.com/document/Tutorial/slpush.htm