How do I code facebook-like browser notifications using AppEngine Channel API? - javascript

I am writing a Python AppEngine app, and need to deliver notifications to browser clients when certain backend events happen. I am using the channel API. I have two issues: multiple page loads within the same tabs and multiple tabs.
Multiple Page Loads
I seem to be unable to reuse the same channel across multiple page loads. An attempt to reconnect to the channel on the new page results in an error with code 0 and no description. I am currently storing the channel token in the datastore and injecting the token into the page. How can I reuse the same channel for multiple page loads within the same tab? This answer suggests iframes are the way. Is recoding the site with iframe my best option here?
Tabs
My understanding is that I need to generate a client ID for each tab the user opens. How should I generate a client ID that will be different for each opened tab? I could just increment an ID on the server, is that the best way?
Thanks in advance,
Aaron

I have been investigating strange channel disconnections in DEV, and it looks like Channel API is much more stable in the live environment than in the development environment.
I created a (somewhat) minimal AppEngine application that creates a channel that persists across page loads. The app reuses a channel token from the datastore.
The code for the app is here: https://github.com/aaronlifshin/channeltest
The app itself is live at http://channeltestaaron.appspot.com/
How to use it?
When you go to http://channeltestaaron.appspot.com/ANYSTRING the app will create a channel and then reuse this channel for any other URLs you open of the form http://channeltestaaron.appspot.com/ANYTHING
Then you can go to http://channeltestaaron.appspot.com/broadcast to cause a message to be sent to all the other pages you've opened.
All pages have a 1-second delay to test the persistence of the channel. This 1-second delay would cause the channel to disappear in dev.
Hope this is helpful.
Aaron

Multiple page loads: according to the answer here you can reuse the token, however need to make sure to use it on one page at a time (it might also be a good idea to avoid page reloads and to have a single-page app that uses hash fragments).
Tabs: the most straightforward way to generate client ID is create a random string, e.g. like this.

Related

How to navigate users to other pages in the website without losing socket connection?

I want to build a simple web application using socket.io and express, the website will include 2 pages:
(Rooms page and room page).
The rooms page is where the user needs to insert his name and he can create his own room or join an existing room from the room list.
On the room page, I want to wait for 2 users and then display a trivia question.
How do I redirect users to the room page from the rooms page without losing socket connection? When I try to do it with HTML tag 'a' with "href" attribute it doesn't work.
I guess it because the page is reloading so how can I navigate to other pages and keep the socket connection on?
You have just described a key reason that Single Page Application frameworks are so popular - you can change the user's view without reloading or interrupting data connections to the server.
In your example, as soon as you request the other page from the server the socket.io connection will disconnect and then reconnect when the next page is ready. You can use console.log statements to confirm this behavior.
So no, it's not possible using Express unless you start considering workarounds like frames or iframes that separate pages, or maybe timestamps on the client that can "catch up" the newly loaded page. Neither are good options.
React, Angular, and Vue are the three most popular SPA frameworks, if your app is advanced enough to need a constant socket.io connection then chances are you will benefit from using one of them.

How do I push mongodb data?

So I have developed a web app as a hobby on Handlebars, Express and Mongoose/MongoDB.
The app let's users create an account and then post advertisements for other users to see and respond to.
All the ads posted by users show up on the index page. So it is common view for all the users on this web app. I am relatively new to web development so to build such a simple app it took me a while but boy I learned a lot!
Now the issue I am facing is, when a user A posts an Ad while the user B is logged in and is currently on the index page (a page that lists all the ads posted) it won't show up for user B unless user B refreshes the page. Rightly so actually because only when the index page's route is hit it will query all the ads and refreshing is basically hitting the index route I get that. But I don't want it that way. I want it to show the new ad on user B's index and pretty much every user's index if there's new ad by any user.
So I did a little research/reading and I learned that I can do it by learning to work with triggers on mongodb and like create some kind of trigger that when a new ad is posted do something. I like the idea but failed to find resources to learn how to use such a thing.
The other option I was suggested was to use socket.io but that too I can't grasp how can I make an entire Ad document work as a socket. I am lost and implementing this feature of dynamically loading ads for all users will complete this hobby project of mine and will help me find a junior dev job in local community.
I request stackoverflow's community to guide me how do I go about doing this and what resources I can use to learn about it.
The socket.io seems to be the best solution for your case. What you will want to do with socket.io is every time a user posts an Ad you use socket.io to notify the rest of the users that there is an update.
If you don't want to send the entire document using the socket you can use the socket to notify the clients and on the client side every time you receive such a notice from the server you will either
a) Refresh the page(not suggested as it will make the user experience unpleasant) which is easier to implement
OR
b) You can use an Ajax request to get the new data from your server and update the fields on the fly(which makes for a better user experience).
Best Way You can come with using Short Polling concept from client side to ask for new data after 1 or 2 seconds (whatsoever count to need ) . Gmail for new inbox mails also uses sync method in a particular fashion . Just ask from server for new data
OR Second option to go through below
On Server Side
Serve index.html page to User A (which is logged in now).Some User B inserts data
Maintain a function or a cron job (checks the count of Total Ads ) Lets say after every 1 minute or so
If there is change in count from the previous total_count , update it and get new mlab documents and send it to function , Let's say push_new_ads which will be sync via socket.io to client
On Client Side
Sync your client_total_count with server_local_count push_new_ads using socket.io and If there is change in count , make a simple fetch api call to get data and appends it to previously fetched array
There is no such way to directly listen the changes in mongodb But you can trigger some changes from oplog using tailable cursors

Dynamic website without client side url handling

I have a challenge that I can't solve. I have made a website with node.js and have all of the code written for the routing including routing for sub-domains. Some location only some users can access, some locations only logged in users can access. I wanted to include a chat for my users so I went along and created one with socket.io and some client side js.
Now I need the site to keep the chat element open which in on a bar across the screen when the client goes to another portion of the website. I have looked into many solutions but almost all of them include some js library like angular.js with the ng-model or ui technique but all include writing code for the client side that handles the url and what to load.
I don't really want to do this method because:
I don't want to re-write all my routes and I am not even sure how to handle the authentication of the users.
I find the client method to be a security issue
My website isn't a single page app, I just want one portion of the website to stay loaded.
Here is some images of what I am wanting:
State 1:
State1
State 2:
State2
Notice that the chat stays but other content was loaded. Also that it went to a different sub domain and a location that is only accessible by logged in users.
Thanks!
I guess you want to maintain state across page refresh, much like e.g. Facebook does. A true and trusted way of doing this is setting a cookie that stores the chat state: open/closed, or store the state on the server. Then on page load, initialize the chat based on this data.

Check if user Likes Page with JS API?

I know this has been asked a bunch of times, but I have only seen serverside solutions.
I'm running an iframe app that is embedded into a page as a tab. I want be test to see if the page is liked or not without prompting the user for anything.
Is there a way to do this with just JavaScript? The platoform we are building on is ASPX and I dont really have the option of going serverside.
Its not available because you need to inspect the http post parameter called signed_request and this isn't available on the client side. If the user has authenticated with your app and given you permissions to read their likes/interests, then you could then check with javascript api but I'm guessing you wouldn't want to make them approve your app just for this.

Running a jquery mobile web app in a disconnected state?

I've been toying with writing a web app using jquery mobile which makes use of forms (cehckboxes, text fields, combo boxes). The tasks the app requires are fairly trivial but the information needs to be updated and sent to a server.
So my question is, say someone uses the app, gets a bunch of data from a server, then loses connection. Will the browser still remember the form fields input and could the user still navigate between pages? From my understanding jquery mobile places all its pages in the same 'webpage' so it's not like it will have to be constantly loading up new data from the server.
My idea is that I'll run some script in the background to check for a connection to a server and when it gets this connection it can go ahead and sync data with the server.
Is this possible or is it a pipe dream?
for jquery mobile it append all the data it had in same page so user can use only those links which are already clicked for the links that user have not touch yet will create problem

Categories

Resources