Is the ononline event supported in a service worker? - service-worker

document.ononline is an event available in the browser. Is there an equivalent event supported by service worker code, which does not have DOM access?
All the sample code I have seen checks network status in the course of handling a request. It would be desirable to respond to network availability immediately for the purposes of committing local updates to the server or cloud.
The best I could find in terms of documentation was https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope and it lists only these events:
onactivate
onfetch
oninstall
onmessage
onnotificationclick
onnotificationclose
onpush
onpushsubscriptionchange
onsync
Of these, sync seems most like what I seek, but it depends on use of a SyncManager, and the documentation for that is fraught with warnings against use in production code.

I'm not sure whether there's an event available in the SW for that. Someone should confirm this.
You could work around this problem by having the ononline event handler logic in your page's JS which could inform the SW of the connectivity changes. This would also be an appropriate place to handle any notifications in the UI for the user.
Spesifically:
SW registers an onmessage handler
Client/page JS registers a handler for the ononline event
When connection changes, the handler notifies the SW via postMessage API
SW receives the connection change msg from the client and acts accordingly
The postMessage API is very useful and can be used to pass basically any data between the page and the SW. Note that there isn't any spesific message for my proposal, just pass something like { "new_status": "online" } etc.

This is an old question but one I'm currently interested in. What I've found is that while MDN currently says it's supported in the (shared) WorkerGlobalScope, I'm sitting on a breakpoint right now in my service worker using Chrome DevTools and the ServiceWorkerGlobalScope does not have an "ononline" property. The "navigator.onLine" indicator appears to work however. You can at least check that and return cached responses immediately.
I added event listeners for online and offline events and neither triggered, so it appears to be unsupported. I can think of plausible reasons for not supporting it, but it would be interesting to hear the real ones.

Related

AWS redrive to source queue in Java

AWs recently added a feature that allows you to send messages from a DLQ back to source queue via a lick of a button "redrive to source". I wanted to know is this possible via an API call.
I know how to extract a message from dlq queue and re send it, But with this new function i was hoping i wouldnt need to handle the messages, but rather just call a method perhaps on the queue and if its configured it would do the redelivery.
Anyone know if this is possible, as im searching in the net.
I believe currently this feature is only available via the management console UI and not as an API

Keeping webrtc streams/connections between webpages

I have a specific issue where I'm using WebRTC (voice and video).
I want to keep a connection/voice/video streams alive between webpages on a website. I thought I could use shared web workers to run in the background?
Any guidance would be great. I've looked at other posts but they're quite old and wondered if anyone had any, more, up-to-date information or ways I could tackle this issue?
UPDATE:
Shared Web Workers are the incorrect way of tackling this problem. Service Workers are the way forward for maintaining after the web page is terminated.
Keeping the webRTC connection alive between page loads seems like a rare use case. Normally, you start a call and remain on a single page. I guess it could make sense if you wanted to embed a customer support like webRTC widget on a site and have that widget follow a user through page navigations under a single domain.
I don't think saving/reusing the blob URL will allow you to reconnect on a page reload for security issues/hijacking potential.
There is the IceRestart constraint which might help. Apparently you can save the SDP info to local storage, reuse the negotiated SDP, then call an IceRestart to quickly reconnect.
As described in section 3, the nominated ICE candidate pair is
exchanged during an SDP offer/answer procedure, which is maintained
by the JavaScript. The JavaScript can save the SDP information on
the application server or in browser local storage. When a page
reload has happened, a new JavaScript will be reloaded, which will
create a new PeerConnection and retrieve the saved SDP information
including the previous nominated candidate pair. Then the JavaScript
can request the previous resource by sending a setLocalDescription(),
which includes the saved SDP information. Instead of restart an ICE
procedure without additional action hints, the new JavaScript SHALL
send an updateIce() which indicates that it has happended because of
a page reload. If the ICE agent then can allocate the previous
resource for the new JavaScript, it will use the previous nominated
candidate pair for the first connectivity check, and if it succeeds
the ICE agent will keep it marked as selected. The ICE agent can now
send media using this candidate pair, even if it is running in
Regular Nomination mode.
https://bugs.chromium.org/p/webrtc/issues/detail?id=979
https://datatracker.ietf.org/doc/html/draft-li-rtcweb-ice-page-reload-02

Logout clients from XMPP

I have an xmpp/ejabberdb app that uses an external service to provide eventing features, but when this service becomes unavailable, I want to disconnect/logout all of my clients. Is this possible? How?
I got it working the way I needed. In fact, I didn't find any simple way to make my own server logout all connected users given some kind of situation, so I dug into ejabberd's code and figured out a way to do it myself.
In ejabberd_c2s.erl module, when a client logs out or it's socket is dropped for some reason, the FSM is terminated, doing all necessary clean up to maintain ejabberd's consistency.
What I had to do was just create an exported function shutdown/1 in this module that calls gen_fsm:send_all_state_event/2 sending a signal for it to terminate.
As for each connection there's one c2s process, I need to call this function for each user.
---UPDATING---
Actually there's no need to create this shutdown function, as ejabber_c2s already has the ability to process 'closed' signal, which does the same thing. So, instead of creating the shutdown function, simply doing ge_fsm:send_event(C2SPid, closed) might be enough.
---UPDATING---
To discover the user's c2s process PID I just use ejabberd_sm:get_session_pid/1 or ejabberd_sm:dirty_get_sessions_list/0 (for all sessions).
This worked fine for me, but if anyone has a better idea, please add here.
Thanks
I don't know the ejabberd specifics, but you could write a custom XMPP component which polls the external service (or listens for presence events, if it's another XMPP component), then logs out users when the service becomes unavailable.

Asyncronously send messages to third party systems - queue?

We have an ASP.NET MVC web app which allows users to publish messages onto a web site. Alongside this, the user is also able to syndicate that message content to other 3rd party systems when they post the message.
At present, this is done synchronously, so when they click the 'Post' button, we persist their message to the database and then notify each 3rd party systems in turn. We need to improve the scalability and durability of this operation so I would like to make the notification aspect of the action asynchronous in some way.
I can think of the following possiblities
Save the 3rd party messages into a database table and have some worker process read items from the table and post to the 3rd party systems.
Use a "proper" message queue of some sort like nServiceBus or RabbitMQ (I have no experience with either of these)
Is there a better way to do this? I'm particularly interested in how to notify the user that the message has been syndicated correctly (since it's ansynchronous) and also how to handle multiple retry failures, at which point the sender should just give up.
Thanks
James
NServiceBus is a great framework for implementing asynchronous communication. If you use it for this use case, you will see many other opportunities for applying messaging for improving the scalability and reliability of your system.
Create a MessagePosted event message that is published after a message is persisted to the database. For each third party system that might be notified of the message, create an event handler class that implements IHandleMessages.
Multiple retry failures is facilitated by NServiceBus, just throw an exception within the event handler if something goes wrong. The event will be resubmitted to the event handler for a configurable number of retries before the event is moved to the error queue.
To notify the user you can for instance create a status view or widget which shows the notification results of the latest messages. If a third party system cannot be notified you can consider sending the user an e-mail so that he can take action.
Use this publish subscribe sample to get up to speed quickly: http://docs.particular.net/samples/pubsub/
You should read this: It explains how to use pub sub with RabbitMQ http://www.rabbitmq.com/tutorials/tutorial-three-java.html

Ideas for web application with external input and realtime notification

I am to build a web application which will accept different events from external sources and present them quickly to the user for further actions. I want to use Ruby on Rails for the web application. This project is a internal development project. I would prefer simple and easy to use solutions for rapid development over high reliable and complex systems.
What it should do
The user has the web application opened in his browser. Now an phone call comes is. The phone call is registered by a PBX monitoring daemon. In this case via the Asterisk Manager Interface. The daemon sends the available information (remote extension, local extension, call direction, channel status, start time, end time) somehow to the web application. Next the user receives a notified about the phone call event. The user now can work with this. For example by entering a summary or by matching the call to a customer profile.
The duration from the first event on the PBX (e.g. the creation of a new channel) to the popup notification in the browser should be short. Given a fast network I would like to be within two seconds. The single pieces of information about an event are created asynchronously. The local extension may be supplied separate from the remote extension. The user can enter a summary before the call has ended. The end time, new status etc. will show up on the interface as soon as one party has hung up.
The PBX monitor is just one data source. There will be more monitors like email or a request via a web form. The monitoring daemons will not necessarily run on the same host as the database or web server. I do not image the application will serve thousands of logged in users or concurrent requests soon. But from the design 200 users with maybe about the same number of events per minute should not be a scalability issue.
How should I do?
I am interested to know how you would design such an application. What technologies would you suggest? How do the daemons communicate their information? When and by whom is the data about an event stored into the main database? How does the user get notified? Should the browser receive a complete dataset on behalf of a daemon or just a short note that new data is available? Which JS library to use and how to create the necessary code on the server side?
On my research I came across a lot of possibilities: Message brokers, queue services, some rails background task solutions, HTTP Push services, XMPP and so on. Some products I am going to look into: ActiveMQ, Starling and Workling, Juggernaut and Bosh.
Maybe I am aiming too hight? If there is a simpler or easier way, like just using the XML or JSON interface of Rails, I would like to read this even more.
I hope the text is not too long :)
Thanks.
If you want to skip Java and Flash, perhaps it makes sense to use a technology in the Comet family to do the push from the server to the browser?
http://en.wikipedia.org/wiki/Comet_%28programming%29
For the sake of simplicity, for notifications from daemons to the Web browser, I'd leave Rails in the middle, create a RESTful interface to that Rails application, and have all of the daemons report to it. Then in your daemons you can do something as simple as use curl or libcurl to post the notifications. The Rails app would then be responsible for collecting the incoming notifications from the various sources and reporting them to the browser, either via JavaScript using a Comet solution or via some kind of fatter client implemented using Flash or Java.
You could approach this a number of ways but my only comment would be: Push, don't pull. For low latency it's not only quicker it's more efficient, as your server now doesn't have to handle n*clients once a second polling the db/queue. ActiveMQ is OK, but Starling will probably serve you better if you're not looking for insane levels of persistence.
You'll almost certainly end up using Flash on the client side (Juggernaut uses it last time I checked) or Java. This may be an issue for your clients (if they don't have Flash/Java installed) but for most people it's not an issue; still, a fallback mechanism onto a pull notification system might be prudent to implement.
Perhaps http://goldfishserver.com might be of some use to you. It provides a simple API to allow push notifications to your web pages. In short, when your data updates, send it (some payload data) to the Goldfish servers and your client browsers will be notified, with the same data.
Disclaimer: I am a developer working on goldfish.
The problem
There is an event - either external (or perhaps internally within your app).
Users should be notified.
One solution
I am myself facing this problem. I haven't solved it yet, but this is how I intend to do it. It may help you too:
(A) The app must learn about the event (via an exposed end point)
Expose an end point by which you app can be notified about external events.
When the end point is hit (and after authentication then users need to be notified).
(B) Notification
You can notify the user directly by changing the DOM on the current web page they are on.
You can notify users by using the Push API (but you need to make sure your browsers can target that).
All of these notification features should be able to be handled via Action Cable: (i) either by updating the DOM to notify you when a phone call comes in, or (ii) via a push notification that pops up in your browser.
Summary: use Action Cable.
(Also: why use an external service like Pusher, when you have ActionCable at your disposal? Some people say scalability, and infrastructure management. But I do not know enough to comment on these issues. )

Resources