Chat program design - chat

I am going to develop a live help chat system with the basic features being similar to http://www.providesupport.com and http://www.liveperson.com/
I am unsure how to structure the application. I want to have a web based chat script for an end user to interact with our support staff who will use an admin console to manage different chats. I am planning on using a mix of PHP/JavaScript/AJAX to implement the end users chat and Java to build the admin panel. There will also be a MySQL database to store settings/chats etc.
The key features I want to include are:
- Support for multiple concurrent chats
- Multiple operators
- Transfer chats between operators
- "User is typing" notifications
- Logging of each chat into database
- Online/Offline mode
I have come up with three possible approaches for the basic architecture of the system, particularly in how the chat element works. I am unsure which approach is best and was hoping you could point me in the correct direct and point out any advantages/disadvantages I have missed.
Approach 1 - Static HTML files for chat
The PHP user chat box writes to and reads from a HTML file which contains the chat. Then reload this file every few seconds to ensure updates are shown. The Java admin end would also do something similar.
Advantages:
- Messages are logged throughout.
- Operators could manage different chats by loading different HTML files
- Different operators can load the same chat, allowing transfer of users
Disadvantages
- User is typing notifications would need some separate method
Approach 2 - MySQL database to store chats
The chat would be written to a MySQL database as each new message is typed. The admin and user end would then check for updates in the database every few seconds and reload the chat windows if it has occurred.
Advantages:
- Messages are logged throughout as each message is stored in DB.
- Operators could manage different chats through different SQL queries
- Different operators can load the same chat, allowing transfer of users
Disadvantages:
- User is typing notifications would need some separate method
- The database would get extremely large
- Constantly querying the database could have high server load and become slow with a large table
Approach 3 - Direct socket connections
The PHP web end has a socket connection directly to the Java admin client that they are talking to. All the chat data goes through this, then when the chat is finished, it is written to the database to be stored.
Advantages:
- Would be quick as each party would know when a new message is received
- "User is typing" messages could be sent over the socket connection
- Data is logged
Disadvantages:
- Socket connection could be lost, therefore ending the chat.
- Not sure how transfer of chat between operators would work
Summary
So, to summarize, which method would be best? Is there a better methods that I have not thought of? I have looked at HTML5 web sockets but I need a good browser compatibility.
In addition to this, how would I achieve having an online/offline indicator depending on whether admin users are logged in?
I am after a more generic overview as opposed to code etc?
Thanks for your help.

Have you considered socket.io in order to get a real cross-browser socket?
Otherwise you could use something that's already developed for this, instead of re-inventing the wheel, like an XMPP JS library that already exists out there.
If you want to implement stuff yourself, your best shot is ajax long-polling, don't have your page reload constantly, rather provide some sort of webservice, and use JS (or jQuery) to communicate with it, and transmit only chat-related data.

Related

RethinkDB - How to stream data to the browser

Context
Greetings,
One day I randomly found RethinkDB and I was really fascinated by the whole real-time changes thing. In order to learn how to use this tool I quickly spinned up a container running RethinkDB and i started making a small project. I wanted to make something very simple therefore i thought about creating a service in which speakers can create room and the audience can ask questions. Other users can upvote questions in order to let the speaker know which one are the best. Obviously this project has a lot of realtime needs that i believe are best satisfied by using RethinkDB.
Design
I wanted to use a vary specific set of tools for this. The backend would be made in Laravel Lumen, the frontend in Vue.JS and the database of course would be RethinkDB.
The problem
RethinkDB as it seems is not designed to be exposed to the end user directly despite the fact that no security concern exists.
Assuming that the user only needs to see the questions and the upvoted in real time, no write permissions are needed and if a user changed the room ID nothing bad will happen since the rooms are all publicly accessible.
Therefore something is needed in order to await data updates and push it through a socket to the client (socket.io for example or pusher).
Given the fact that the backend is written in PHP i cannot tell Lumen to stay awake and wait for data updates. From what i have seen from the online tutorials a secondary system should be used that should listen for changes and then push them. (lets say a node.js service for example)
This is understandable however i strongly believe that this way of transferring the data to the user is inefficient and it defeats the purpose of RethinkDB.
If I have to send the action from the client's computer (user asks a question), save it to the database, have a script that listens for changes, then push the changes to socket.io and finally have the client (vue.js) act when a new event arrives, what is the point of having a real-time database in the first place?
I could avoid all this headache simply by having the Lumen app push the event directly to socket.io and user any other database system instead.
I really cant understand the point of all this. I am not experienced with no-sql databases by any means but i really want to experiment with them.
Thank you.
This is understandable however i strongly believe that this way of transferring the data to the user is inefficient and it defeats the purpose of RethinkDB.
RethinkDB has no built in mechanism to transfer data to end-users. It has no access control (in the conventional sense) as well. The common way, like you said, is to spin up one / multiple node instance(s) running socket.io. On each instance you can listen on your RethinkDB change streams and use socket.io's broadcast functionality. This would be a common way, but as RethinkDB's streams are pretty optimized, you could also open a change stream for every incoming socket.io connection.

Recommendations for multi-user Ionic/CouchDB app

I need add multi-user capability to my single-page mobile app developed with Ionic 1, PouchDB and CouchDB. After reading many docs I am getting confused on what would be the best choice.
About my app:
it should be able to work offline, and then sync with the server when online (this why I am using PouchDB and CouchDB, working great so far)
it should let the user create an account with a username and password, which would then be stored within the app so that he does not have to log in again whenever he launches the app. This account will make sure his data are then synced on the server in a secure place so that other users cannot access it.
currently there is no need to have shared information between users
Based on what I have read I am considering the following:
on the server, have one database per user, storing his own data
on the server, have a master database, storing all the data of all users, plus the design docs. This makes it easy to change the design docs in a single place, and have them replicated on each user database (and then within the PouchDB database in the app). The synchronization of data, between the master and the user DBs, is done through a filter, so that only the docs belonging to one user (through some userId field) are replicated to this user's database only
use another module/plugin (SuperLogin? nolanlawson/pouchdb-authentication?) to manage the users from the app (user creation, login, logout, password reset, email notification for password lost, ...)
My questions:
do you think this architecture is appropriate, or do you have something better to recommend?
which software would you recommend for the users management? SuperLogin looks great but needs to run on a separate HTTP server, making the architecture more complex. Does it automatically create a new database for each new user (I don't think so)? Nolanlawson/pouchdb-authentication is client-only, but does it fit well with Ionic 1? Isn't there a LOT of things to develop around it, that come out of the box with SuperLogin? Do you have any other module in mind?
Many thanks in advance for your help!
This is an appropriate approach. The local PouchDBs will provide the data on the client side even if a client went offline. And the combination with a central CouchDB server is a great to keep data synchronized between server and clients.
You want to store the users credentials, so you will have to save this data somehow on your client side, which could be done in a separate PouchDB.
If you keep all your user data in a local PouchDB database and have one CouchDB database per user on the server, you can even omit the filter you mentioned, because the synchronization will only happen between this two user databases.
I recommend SuperLogin. Yes, you have to install NodeJS and some extra libraries (namely morgan, express, http, body-parser and cors), and you will have to open your server to at least one new port to provide this service. But SuperLogin is really powerful to manage user accounts and user databases on a CouchDB server.
For example, if a user registers, you just make a call to SuperLogin via http://server_address:port/auth/register, query the user name, password etc. and SuperLogin not only adds this new user to the user database, it also creates automatically a new database only for this user. Each user can have multiple databases (private or shared) and SuperLogin manages the access rights to all these databases. Moreover, SuperLogin can also send confirmation emails or resend forgotten passwords (an access token, respectively).
Sure, you will have to configure a lot (but, hey, at least you have all these options), and maybe you even have to write some additional API for functionality not covered by SuperLogin. But in general, SuperLogin saves a lot of pain regarding the development of a custom user management.
But if you are unsure about the server configuration, maybe a service such as Couchbase, Firebase etc. is a better solution. These services have also some user management capabilities, and you have to bother less with server security.

iPhone / Android realtime communication, XMPP, raw TCP?

I have an app that has 2 versions : 1 on iPhone, 1 on Android.
I want my 2 apps to communicate in real time. The use cases are :
User A sees a friends list, pick a user B and click on "share an item"
User B get a notification saying that user A wans to share an item with him
User B accepts, the transaction takes place, and both users are notified that it goes well.
I thought about using a simple HTTP transaction, but that would polling for the user therefore not a nice user experience.
I think XMPP would fit nicely, but I'm not quite sure how flexible this solution can be ( what if I want to keep my users information on a separate server also etc. ). I also consider using a raw TCP socket ( Node.js on the server is fairly easy to operate ).
What's the best solution at the moment ?
Well, your requirements are pretty much:
Real time
Friend list
Presence
Sharing of data
These are all features of XMPP, and there are library implementation available in multiple languages. Smack for Java and xmppframework for Objective C will cover your particular use case.
You could of course write this yourself from the socket layer up, but why bother when there are existing standardized protocols and libraries available to do what you need. This way when you want to add Blackberry or any other platform to your list, I am sure
you can easily find the right library to support your app without having to build from the ground up.

SQLite and iphone

I am sorry for asking such a noob question. I know that one way of storing data on the iphone via database is using SQLite, but after reading for a while it seems that the database is local and therefore each application has a copy of the database? is this right? if that is the case then what if I have two ipod with the same apps. and ipod A wants to update the database, then the data isn't reflected on ipod B?? Sorry for the noob questions
You overcome this by having a server which can synchronise the data between the apps. This is actually a much bigger problem than you might first think. In sonatribe.com we're having to consider situations where users aren't connected to the internet - so we queue the users actions and then push the data to the server when the device is connected. You then have to consider which database is the priority? Which one over writes the other when there are conflicts.
We also release new data for new events regularly - this data is then synchronised when the app is fired up.
One of the lessons we learned was that it's better to keep the number of calls down - connecting is expensive - but once connected the flow of data is fast.
FWIW - we went with MonoTouch - and the main reason was for the integration with WCF and the data capabilities (LINQ) of .NET. Using the SIlverlight profile and svcutil it's easy to get connected and communicate with web services passing complex objects over the wire - very handy for this sort of thing.
You also need to consider users who are on a limited data contract. We have the ability to turn off auto synch with the server in the settings. This is also useful for when our users are actually at the music festivals - in the UK, reception is renowned for being bad at events like this due to the sheer volume of people in one space. Although this is improving, users will appreciate the fact that they can stop the app communicating with a server on their behalf.

Keeping iPhone application in sync with GWT application

I'm working on an iPhone application that should work in offline and online modes.
In it's online mode it's supposed to feed all the information the user enters to a webservice backed by GWT/GAE.
In it's offline mode it's supposed to store the information locally, and when connection is available sync it up to the web service.
Currently my plan is as follows:
Provide a connection between an app and a webservice using Protobuffers for efficient over-the-wire communication
Work with local DB using Core Data
Poll the network status, and when available sync the database and keep some sort of local-db-to-remote-db key synchronization.
The question is - am I in the right direction? Are the standard patterns for implementing this? Maybe someone can point me to an open-source application that works in a similar fashion?
I am really new to iPhone coding, and would be very glad to hear any suggestions.
Thanks
I think you've blurring the questions together.
If you've got a question about making a GWT web interface, that's one question.
Questions about how to sync an iPhone to a web service are a different question. For that, you don't want to use GWT's RPCs for syncing, as you'd have to fake out the 'browser-side' of the serialization system in your iPhone code, which GWT normally provides for you.
about system design direction:
First if there is no REAL need do not create 2 different apps one GWT and other iPhone
create one but well written GWT app. It will work off line no problem and will manage your data using HTML feature -- offline application cache
If it a must to create 2 separate apps
than at least save yourself effort and do not write server twice as if you go with standard GWT aproach you will almost sertanly fail to talk to server from stand alone app (it is zipped JSON over HTTP with some tricky headers...) or will write things twise so look in to the RestLet library it well supported by the GAE.
About the way to keep sync with offline / online switching:
There are several aproaches to consider and all of them are not perfect. So when you conseder yours think of what youser expects... Do not be Microsoft Word do not try to outsmart the user.
If there at least one scenario in the use cases that demand user intervention to merge changes (And there will be - take it to the bank) - than you will have implement UI for this - than there is a good reason to use it often - user will get used to it. it better than it will see it in a while since he started to use the app because a need fro it is rare because you implemented a super duper merging logic that asks user only in very special cases... Don't do it.
balance the effort. Because the mess that a bug in such code will introduce to user is much more painful than the benefit all together.
so the HOW:
The one way is the Do-UnDo way.
While off line - keep the log of actions user did on data in timed order user did them
as soon as you connected - send to server and execute them. Same from server to client.
Will work fine in most cases as long as you are not writing a Photoshop kind of software with huge amounts of data per operation. Also referred as Action Pattern by the GangOfFour.
Another way is a source control way. - Versions and may be even locks. very application dependent. DBMS internally some times use it for transactions implementations.
And there is always an option to be Read Only when Ofline :-)
Wonder if you have considered using a Sync Framework to manage the synchronization. If that interests you can take a look at the open source project, OpenMobster's Sync service. You can do the following sync operations
two-way
one-way client
one-way device
bootup
Besides that, all modifications are automatically tracked and synced with the Cloud. You can have your app offline when network connection is down. It will track any changes and automatically in the background synchronize it with the cloud when the connection returns. It also provides synchronization like iCloud across multiple devices
Also, modifications in the Cloud are synched using Push notifications, so the data is always current even if it is stored locally.
Here is a link to the open source project: http://openmobster.googlecode.com
Here is a link to iPhone App Sync: http://code.google.com/p/openmobster/wiki/iPhoneSyncApp