I have a software architecture problem.
I have to design an IOS application which will communicate with a Linux application to get the state of a sensor, and to publish an actuator command. The two applications run in a Local network with an Ad-Hoc WiFi connection between the IOS device and the Linux computer.
So I have to synchronize two values between two applications (as described in figure 1). In a Linux/Linux system, I resolve this kind of problem thanks to any publisher / subscriber middleware. But how can I solve this problem in an IOS / Linux world ?
Actually the Linux application embed an asynchronous TCP Server, and the IOS application is an asynchronous TCP client. Both applications communicate through the TCP Socket. I think that this method is a low level method, and I would like to migrate the communication layer to a much higher level Service based communication framework.
After some bibliographic research I found three ways to resolve my problem :
The REST Way :
I can create a RESTful Web Service which modelize the sensor state, and which is able to send command to the actuator. An implementation of a RESTful web service client exists for IOS, that is "RESTKit", and I think I can use Apache/Axis2 on the server side.
The RPC Way :
I can create on my Linux computer a RPC service provider thanks to the libmaia. On the IOS side, I can use xmlrpc (https://github.com/eczarny/xmlrpc). My two programs will communicate thanks to the service described in the figure below.
The ZeroConf way :
I didn't get into detail of this methods, but I suppose I can use Bonjour on the IOS side, and AVAHI on the linux side. And then create custom service like in RPC on both side.
Discussion about these methods :
The REST way doesn't seem to be the good way because : "The REST interface is designed to be efficient for large-grain hypermedia data transfer" (from the Chapter 5 of the Fielding dissertation). My data are very fined grain data, because my command is just a float, and my sensor state too.
I think there is no big difference between the ZeroConf way and the RPC Way. ZeroConf provide "only" the service discovering mechanism, and I don't need this kind of mechanism because my application is a rigid application. Both sides knows which services exists.
So my question are :
Does XML RPC based method are the good choice to solve my problem of variable synchronization between an iPhone and a Computer ?
Does it exist other methods ?
I actually recommend you use "tcp socket + protobuf" for your application.
Socket is very efficient in pushing messages to your ios app and protobuf can save your time to deliver a message instead of character bytes. Your other high level proposal actually introduces more complications...
I can provide no answers; just some things to consider in no particular order.
I am also assuming that your model is that the iOS device polls the server to synchronize state.
It is probably best to stay away from directly using Berkeley sockets on the iOS device. iOS used to have issues with low level sockets not connecting after a period of inactivity. At the very least I would use NSStream or CFStream objects for transport or, if possible, I'd use NSURL, NSURLConnection, NSURLRequest. NSURLConnection's asynchronous data loading capability fits well with iOS' gui update loop.
I think you will have to implement some form of data definition language independent of your implementation method (RES, XML RPC, CORBA, roll your own, etc.)
The data you send and receive over the wire would probably be XML or JSON. If you use XML you would have to write your own XML document handler as iOS implements the NSXMLParser class but not the NSXMLDocument class. I would refer JSON as the JSON parser will return an NSArray or NSDictionary hierarchy of NSObjects containing the unserialized data.
I have worked on a GSOAP implementation that used CFStreams for transport. Each request and response was handled by a request specific class to create request specific objects. Each new request required a new class definition for the returned data. Interactivity was maintained by firing the requests through an NSOperationQueue. Lots of shim here. The primary advantage of this method was that the interface was defined in a wsdl schema (all requests, responses, and data structures were defined in one place.
I have not looked at CORBA on iOS - you would have to tie in C++ libraries to your code and change the transport to use CFStreams Again, lots of shim but the advantage of having the protocol defined in the idl file. Also you would have a single connection to the server instead of making and breaking TCP connections for each request.
My $.02
XML RPC and what you refer to as "RESTful Web Service" will both get the job done. If you can use JSON instead of XML as the payload format, that would simplify things somewhat on the iOS side.
Zeroconf (aka bonjour) can be used in combination with either approach. In your case it would allow the client to locate the server dynamically, as an alternative to hard-coding an URL or other address in the client. Zeroconf doesn't play any role in actual application-level data transfer.
You probably want to avoid having the linux app call the iOS app, since that will complicate the iOS app a lot, plus it will be hard on the battery.
You seem to have cherry picked some existing technologies and seem to be trying to make them fit the problem.
I would like to migrate the communication layer to a much higher level Service based communication framework
Why?
You should be seeking the method which meets your requirements in terms of available resources (should you assume that the client can maintain a consistent connection? how secure does it need to be?) However besides functionality, availability and security, the biggest concern should be how to implement this with the least amount of effort.
I'd be leaning towards the REST aproach because:
I do a lot of web development so that's where my skills lie
it has minimal dependencies
there is well supported code implementing the protocol stack at both ends
it's trivial to replace either end of the connection to test out the implementation
it's trivial to monitor the communications (if they're not encrypted) to test the implementaiton
adding encryption / authentication does not change the data exchange
Regards your citation, no HTTP is probably not the most sensible for SCADA - but then neither is iOS.
Related
I want to implement a peer-to-peer video chat feature for a web application I am currently developing. After doing my research, I've decided that using webRTC's Javascript APIs is the way to go. The application uses AngularJS in the front end and Ruby on Rails in the back end. The main issue I'm encountering while conceptualizing this application is linking the front end with the backend, and creating and maintaining the connection between user streams.
For the signaling aspect of the network, I want to utilize ActionController::Live and the Ruby gem em-event source to push live messages from the server to users and indicate which of their connections are online. Then, when they are ready to make a connection, they will create a custom room and the URL will be sent to the user that they wish to connect with, creating their offer. Once the user clicks on the link sent to them, they send back their answer. When the user responds, the ICE candidate process will begin for each of the users. Do you think that this is a sufficient signaling channel to set up the PeerConnection? What other major players am I missing?
From the research that I have done about WebRTC's RTCPeerConnection, once the initial connection is set up, and both users have public IP addresses corresponding to their stream, the connection is sustained through RTCPeerConnection, more specifically getPeerConnection(). Am I wrong? Are there other factors that I am not considering?
WebRTC makes the process of creating MediaStreams very simple with their getUserMedia method. Once these streams are created they can be added to the RTCPeerConnection that was established. Both as local and remote streams.
If you have any other suggestions for me, please let me know. I want to create this feature using webRTC, it seems like so much fun
There are certainly many ways to handle the call signaling so I'm not going to comment specifically on your approach. I will say that if you plan on supporting ICE trickling the ICE candidates will start flowing very early in the process so you really need an open signalling channel between your peers almost immediately when trying to connect to a peer.
We developed our solution for WebSphere on top of MQTT which is an open, and very simple pub/sub protocol. You can use any open MQTT broker with the protocol and there are a number of open source components available to make WebRTC development extremely easy including an AngularJS WebRTC module (angular-rtcomm), a core pure JavaScript module and much more. We also released a simple JSON based protocol as part of this open source solution. You can take a look at the signaling protocol. You can also read more details about the overall solution here (www.wasdev.net/webrtc). Here you'll find the base JavaScript libraries as well as a number of open source sample solutions. All of these can be forked on github.
In general you want to build your signaling on a protocol that will allow you to grow over time. It should work well for the web and mobile apps. From our experience it took a lot of time to get all this to work well and our goal was to not only support peer-to-peer calls but to support using media resources like Dialogic's XMS PowerMedia server on the backend for multiway support, record/playback and more. We also needed to support federation via SIP trunking so we wanted to make sure the protocol could be easily translated to SIP signaling while also supporting transcoding between media protocols like VP8 and H.264.
Note that if you're looking to only support peer-to-peer calling between WebRTC clients you can do that with these rtcomm open source components only, including an open MQTT broker and save yourself a ton of time. You can literally get something up and running in a matter of hours. The developer version of the WebSphere Liberty beta with the new rtcomm-1.0 service enabled also includes a built in MQTT broker and supports the open WebRTC signaling protocol linked above. You can use WebSphere for development and deploy a single server of this in production for free. You can also use Ruby on Rails with Liberty as well if you'd like.
Even if you decide not to use Liberty you can use all the open source components along with something like Mosquito (which is an open source MQTT broker) to get a solution off the ground quickly. There are also a number of MQTT clients available for many different programming languages including JavaScript, Java, etc. Check out https://eclipse.org/paho/. If you decide to build you're own signaling protocol you might still find these open source components helpful to see how we approached integration with the WebRTC PeerConnection.
I am developing a gaming server for playing cards that needs a persistent connection between clients and this server.
so the server will accept connections from multiple clients, each of them has been developed with a different programming language.
I know that C# uses .Net remoting and java uses RMI, but I don't know if there is any middleware that can be used for various programming languages.
Any ideas ?
Yes there are plenty ...
There are two things you need to think about:
In which format do you want to transfer the data:
text (XML, JSON)
Binary (Protocol Buffers, ...)
How do you want to communicate with the server
HTTP (REST, WEB Services, ...)
Messaging (ZeroMQ, ...)
other protocols (RPC, RMI, ...)
Most of the communication works one way to the server and the server answers. This way for an interactive card game, you'd need to bug the server every few seconds if something has changed. Even though, it's the easiest way, it can introduce high latencies.
A way around this, would be:
Streaming - you can open a stream as a response and feed updated data to the client
bi-directional communication
Since bi-directional communication is almost never possible (because clients are in private networks behind firewalls) let's have a look at streaming.
We've implemented ~5-6 years ago streaming from C++ SAO-WebService to a .net client and it worked perfectly fine. http://www.webrtc.org/ is something new, for Real-Time-Communication (RTC) on the web. There are server endpoints implemented the most common languages / technologies and client endpoints shouldn't be limited to JavaScript only. But if you want to go more low-end, you can also always open a socket connection to the server and listen on incoming messages. However you loose the benefits of HTTP and other high level protocols.
I've explained parts of this in more detail, when answering the following question: What is the use of REST in distributed web application
I have already developed a Clinic management application for Allergy Control Clinics which stores patients' medical files and test results in a database and generates reports for analysis.
there's a section for storing spirometry results in the database. currently i get results
from an Excel file which is exported by WinspiroPro (the application that comes with spirolab devices) and store them in the database.
few days ago i came across the word "HL7" which seems to be a Standard protocol for communicating with these medical devices, so i can directly get the results from the device using Delphi.
also in spirolab device user manual it is mentioned that the device is compatible with this system.
now my question is, how can I implement this system (HL7) in delphi?
Thanks
As is usual with these kind of inter-professional standards, you need to pay to get them, at least on http://www.hl7.org in this case.
If I search around on the net, there may be existing tools that you can use, or have a look how they work internally:
http://code.ohloh.net/search?s=HL7
https://code.google.com/hosting/search?q=HL7&sa=Search
http://sourceforge.net/directory/?q=HL7
HL7 is not bound to a specific transport layer. It is a protocol on the application level, the seventh layer of the ISO 7-layer-model, hence Level 7. It describes messages and the events, when this messages should be send.
It just gives some recommendations how to do message transfer on the subjacent layers, e.g. MLLP with tcp socket communication. But in principle you are free to use any transport layers you want, may it be direct socket communication, file transfer or what ever.
Although most systems now can use tcp, it is also possible to use HL7 with different underlying transport protocols as RS232. If I remember right, there was also an example about message transfer / coupling with RS232 in the implementation guides of the documentation. And yes, the documentation and protocol standard documetation is free after registering.
Did you ask your provider for the WinspiroPRO version with HL7 ability? Maybe it supports already socket communication with tcp.
Otherwise you either need access to the sourcecode of ldTCPCClient and replace the tcp part with an RS232 part or you have to use a software just for parsing/building (unmarshalling/marshalling) of HL7 messages together with a software, that handles the transportation level.
By the way, just from the name, I guess that ldTCPclient is not apt for your need, as you will probably need a host and not a client component.
Obviously there are multiple steps and phases of implementing such a thing.
I was thinking I would eventually have a webserver that takes http json requests from the ios app, and then queries the cassandra backend and sends results back. I could load balance and all that fancy stuff still, and also provide a logical layer on server side, and keep the client app lightweight.
I'm not sure i understand how cassandra clients fit though. It seems like the cassandra objective c client could eliminate the need for the above approach.
I saw another question and answer but it wasnt clear, perhaps because it varys on the need.
An iPhone app should not directly connect to a Cassandra backend or any other DB store.
First of all, talking to a database often requires adapting a very specific binary protocol (for Cassandra in particular, binary CQL or Thrift). Writing an adapter that would let your Objective-C app communicate in this binary protocol is a major piece of work, and could easily cost more than the rest of your app in effort. If you hide the DB behind a web-server, however, you will be able to select from a variety of existing adapters available in different server-side languages, meaning that you don't need to redo all that low-level work. You'll only be responsible for a relatively small piece of server-side code that would translate your REST queries and forward them to one of the Cassandra adapters (which expose easy-to-use interfaces).
Secondly, if you wanted to connect to a remote database from the phone, your database server would have to open its ports to the internet at large, which is a very bad security practice, even if you use SSL and user credentials. Again, if you hide behind a web server, you will be putting in a layer of technology that has evolved for decades to remain secure on the public internet.
Finally, having your phone talk to Cassandra directly is a poor architectural pattern. When you write apps that communicate on the internet, you want them to know as little as possible about each other, only how to talk to each other (preferably in a standard protocol). That way you can replace or upgrade individual components while keeping everything else the same. This may not sound like a lot, but is actually the main reason why phones, or web browsers, don't directly talk to databases. (If this setup were a good idea in principle, the first two problems could be easily solved given enough engineering effort.)
The approach you first suggested with JSON and the web server is the only correct way to go.
Use something like RESTful API, there are many reasons for that.
if your servers ip addresses change you have to update all client, if you add more nodes you will need to update all clients, if you decide to upgrade your cassandra and some functions change your clients will break and you need to update all clients.
Please read before tagging as duplicate.
I'm creating a set of applications which rely on smart cards for authentication. Up to now, each application has controlled the smart card reader individually. In a few weeks, some of my customers will be using more than one application at the same time. So, I thought maybe it would be more practical to create a service application which controls the authentication process. I'd like my desktop applications to tell the service application they are interested in the authentication process, and the service application would then provide them with information about current user. This part is easy, using named pipes. The hard part is, how can the service tell the desktop applications that an event has occurred (UserLogIn, UserLogOut, PermissionsChanged, ... to name a few). So far I have two methods in mind. CallBack functions, and Messages. Does anyone have a better idea? I'm sure someone has.
You want do to IPC (Inter Process Communication) with Delphi.
There are many links that can help you, Cromis IPC is just one to give you an idea what you are after.
A similar SO question to yours is here.
If you want to go pure Windows API, then take a look at how OutputDebugString communications is implemented.
Several tools can listen to the mechanism and many apps can send information to it.
Search for DBWIN_DATA_READY and DbWin32 for more information on how the protocol for OutputDebugString works.
This and this are good reading.
When it gets into IPC, some tips:
Do not be tied on one protocol: for instance, if you implements named pipe communication, you would later perhaps need to run it over a network, or even over HTTP;
Do not reinvent the wheel, nor use proprietary messages, but standard formats (like XML / JSON / BSON);
Callbacks events are somewhat difficult to implement, since the common pattern could be to implement a server for each Desktop client, to receive notifications from the server.
My recommendation is not to use callbacks, but polling on a stateless architecture, on the Desktop applications. You open a communication channel with the server, then every second / half second (use a TTimer in your UI), you make a small request asking for what did change (you can put a revision number or a time stamp of your last retrieval). Therefore, you synchronize your desktop data with pending events. Asking for updates on an existing connection is very fast, and will just send one IP packet over the network back and forth, if nothing changed. It is a very small task, and won't slow down nor the client nor the server (if you use some in-memory cache).
On practice, with real application, such a stateless architecture is very responsive, from the end-user point of view, and is much more easy to deploy. You do not need to create a server on each desktop application, so you don't have to open firewall ports or such. Since HTTP is stateless, it is even Internet friendly.
If you want to develop services, you can use DataSnap, something like RemObjects or you can try our Open Source mORmot framework which is able to create interface-based services with light JSON messages over REST, either in-process, using GDI messages, named pipes or TCP/HTTP - for free, with unbeatable performance, build-in security, and from Delphi 6 up to XE2. For your event-based task, just using the Client-Server ORM available in mORMot could be enough: create a table/class storing the events (you can even define a round-robin in-memory storage - no need to use SQLite3 engine nor a DB here), then ask for all pending events since the last refresh. And the server can safely be a background service, or a normal application - some mORMot users even have the same executable able to be either a stand-alone application, a server service, an application server, or a UI client, just by changing the configuration.
Edit / announcement:
On the mORMot roadmap, we added a new upcoming feature, to easily implement one-way callbacks from the server.
That is, add transparent "push" mode to our Service Oriented Architecture framework.
Aim is to implement notification events triggered from the server side, very easily from Delphi code, via some interface definitions, even over a single HTTP connection - for instance, WCF does not allow this: it will need a dual binding, so will need to open a firewall port and such.
It will used for easy Event Collaboration, via a publish / subscribe pattern, and allow Event Sourcing. I will try to make it implement the two modes: polling and lock-and-wait. A direct answer to your question.
You can use a simple TCP socket connection (bidirectional) to allow asynchronous server to client messages on the same socket.
An example is the Indy TIdTelnetClient class, it uses a thread for incoming messages from the server.
You can build a similar text-based protocol and only need a Indy TCP server instance in the service, and one Indy Client instance in the application(s).