3

I'm new in this area and a little bit confused about my current thoughts on a web-service implementation for my application. I want to synchronize all connected clients with the current data on a MySQL DB. I came up to use web-services as for coordination purposes, but I got stuck.

The way I tried to implement it is...

The web-service is running a deamon to check/listen on CRUD operations affecting DB data. Once an CRUD operation has been occured it undetakes to notify all the connected clients and each client in turn refreshes the JTable with current DB data and informs the user with the change that took place on the DB.

This is where I'm stuck...

The way I'm thinking it's (maybe?) wrong, since conceptually web-services are awaiting for client requests and then send him the corresponding response. But here, there is no client requests. The web-service just sends a response (noification), which must multicast since it's unaware of a "calling" client -there's no request.

Therefore, in order a client to send a request it must "cron" all the time the web-service if a change on the DB has been occured. Then the web-service responts as true or false with the CRUD details (CRUDEventFired(event_type, event_details)). But, this is not optimal as it will create big and (much of time) useless traffic especially when there is no CRUD operation occured. Also, there will be two different deamons (one in web-service and the other in client-app) that check/listen for the same type of event and that's redundant.

Also, with that implementation it seems that there's no need for a web-service at all and the code to check the DB for changes could be implemented in the client. On the other hand setting the client responsible for the DB changes would require to code the same functions in different platforms (desktop, ios, android, etc), while setting the web-service as the coordinator for data synchronization between clients would require to code only once the appropriate function and each client simply implement its own NotificationListener().

Is it wrong the way I'm thinking using web-services? How it should be changed? Do I even need to use web-services?

I attach my diagram for your convinience.

diagram

1
  • If you genuinely want to synchronise databases, not just maintain a stream of roughly accurate updates with occasional full re-syncs, then you have a hard problem. You should consider using an existing distributed database or one with synchronisation, such as CouchDB.
    – pjc50
    Commented May 15, 2015 at 13:14

2 Answers 2

1

I am not a specialist but here are my two cents. I assume that your webservice runs on a Java EE application server.

  • all the writes to the DB should come from your application server so you should be able to generate events in your code every time you write to the DB
  • instead of webservice which are best for queries from the client, you could use either websockets or a message queue (typically a JMS queue)

Although having the clients write to the DB directly may seem appealing at first (it's easier to understand) it can quickly become a mess. For example, making changes to your DB going forward may require upgrading all clients.

3

It sounds like you are looking to implement push notifications from your back-end service to each front-end client.

Two options come to mind:

  1. WebSockets will allow your clients to maintain a persistent two-way communication channel with the server. Updates on the client can be sent along the persistent channel, and when the web-server receives a change to the data store, it can propagate it out to each connected client. Using this, each client will probably (more on this later) have the most updated data whenever it wants to make a change to it

  2. HTTP Long Poll is an older method (that works quite well) that utilizes HTTP with long timeouts to accomplish something similar to push updates. Each client opens a HTTP request for some resource and has a long timeout (say, 2 minutes for example). When something changes, the server will respond with the new data, otherwise, it will wait for the full 2 minutes before sending a 304 NOT MODIFIED response to the server. In this way, the client can get notifications pretty quickly, but without constantly polling.

Both of these ideas can be read up on here: https://en.wikipedia.org/wiki/Push_technology#HTTP_server_push

Both of these options suffer from the possibility that two clients will want to make updates at the same time, and one my overwrite the other. In this way it is easy for your data-store to become out of sync or have logical inconsistencies in it. If you would like to avoid this, as pjc50 mentioned, you may want to consider using a distributed database.

For those who will think it is useful, here is some pseudo-code for long-polling:

long-poll client & server pseudo-code

/**
 * Handles long-poll request for one client and sends updated
 * content to the client when it changes, or a 304 NOT MODIFIED
 * response if it doesn't change within the timeout period
 */

handleClientRequest(HTTRequest clientRequest) {
    String uri = clientRequest.getURI();
    int timeout = clientRequest.getTimeout();

    /* Wait for the resource to change. You should use
     * a more sophisticated waiting scheme, like semaphores,
     * java monitors, or any number of thread synchronization
     * techniques
     */
    while ((resource hasnt changed) && (total wait time < timeout))
        sleep(timeout / 100)

    if (resource did change)
        send new content
    else
        send HTTP 304 NOT MODIFIED response
}

/**
 * Continually sends long-poll requests to the server,
 * and updates data whenever it changes
 */
clientLongPoll(uri) {
    int timeout = 120 // seconds

    while (true) {
        HttpRequest request = new Request(uri);
        request.setTimeout(timeout);

        /* this will hang until the server responds, up to 2 minutes */
        HttpResponse response = request.send()  
        if (resposne.contentChanged() == true)
            update local data store
    }
}

Web socket libraries usually rely on an event-based scheme (onConnected(), onNewMessage(), onDisconnected(), etc...), but each library is different. The basic idea is that whenever a client starts up, it should contact the server to initiate a WebSockets connection, and from there, each can send messages back and forth whenever their local data changes.

3
  • I would like to thank you for your detailed answer. I'm currently thinking of implementing my stated scenario using WebSockets or a RESTful Web-Service with push notifications. As, I'm new on these technologies and how they bind together, most of these are still not clarified in my mind. I cought the "behind-the-scenes" idea, but I'm missing the way and what steps I have to take in order to implement it. Commented Jul 13, 2015 at 18:55
  • John, I've added some updates to my original post, let me know if you have questions. For long-polling, you will need to set up a RESTFUL service (not required, but it likely will make the most sense) and have each client ask for updates using the timeout scheme. The web service will lie between your DB and your clients -- each client goes through the app server, and the app server can update the DB when needed. For long polling, the app server will still handle communication, but instead of a rest service you will need to implement a web-socket service, likely that uses a websocket library
    – nmio
    Commented Jul 13, 2015 at 19:51
  • I'm really grateful. The info provided is very helpful. But, I have to study about REST Web-Services and Web-Sockets to clear out their differences and various implementations. Also, my project will run both on desktop and android platforms. As, for the 2nd one, I've read that long-polling is a bad technique as it will drain out the battery. I'll study and come back. Best regards, John. Commented Jul 15, 2015 at 11:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.