Im building a social platform and just started on the websocket portion. I'm having trouble understanding where to hook my auth into the Vert.x SockJsHandler. I found a code example using "SockJsServer" via vertx.createSockJsServer here but it doesnt seem like that exists in current versions:
https://github.com/michalboska/codingbeer-vertx/blob/auth-experiment/src/main/java/ch/erni/beer/vertx/HTTPServerVerticle.java
The only hook Im aware of in current version is:
return SockJSHandler.create(vertx).bridge(options) {event ->
logger.info{ "socket event: ${event.type()}" }
event.complete(true)
}
I see event.socket().webUser() and .webSession() exists but am unclear how/where that would get set. So my question is, will I need to create an auth handler on the initial handshake only and if so, where? If a js client needs to receive notifications for say, a message from a specific chatroom they are a member 'chat123', should I register unique handlers for chat123, or somehow iterate over event.socket().webUser() for valid ids each time?
Most vert.x docs are offline with the new site migrating to vert.x 4 so infos a bit hard to find at the moment.
Related
I'm working on an app that gets a list of documents/source URL from an api. I'd like to periodically check for new or updated contents within that API so users can update saved items in the database. I'm at a loss on the correct wording to search, thus Google and Stack Overflow have both failed me. My fetching function is below:
The URL for the API is https://api.afiexplorer.com
private fun fetchPubs() {
_binding.contentMain.loading.visibility = View.VISIBLE
request = JsonArrayRequest(
Request.Method.GET,
Config.BASE_URL,
JSONArray(),{ response ->
val items: List<Pubs> =
Gson().fromJson(response.toString(), object : TypeToken<List<Pubs>>() {}.type)
val sortedItems = items.sortedWith(compareBy { it.Number })
pubsList?.clear()
pubsList?.addAll(sortedItems)
// Hardcoded pubs moved to Publications Gitlab Repo
// https://gitlab.com/afi-explorer/pubs
_binding.contentMain.recyclerView.recycledViewPool.clear()
adapter?.notifyDataSetChanged()
_binding.contentMain.loading.visibility = View.GONE
setupData()
Log.i("LENGTH OF DATA", "${items.size}")
},
{error ->
println(error.printStackTrace())
Toasty.error(applicationContext, getString(string.no_internet), Toast.LENGTH_SHORT, true).show()
}
)
MyApplication.instance.addToRequestQueue(request!!)
}
private fun setupData(){
adapter = MainAdapter(applicationContext, pubsList!!, this)
_binding.contentMain.recyclerView.adapter = adapter
}
I tried using ChatGPT to see if that would get me started and that failed miserably. Also searched Google, Reddit and Stack Overflow for similar projects, but mine is a unique scenario I guess. I'm just a hobbyist and intermediate dev I guess. First time working with Volley, everything works, but I would like to find a way to send a notification (preferably not Firebase) if there is updated info within the API listed above. I'm not sure if this is actually doable.
Are you asking if you can somehow find if the remote API has changed its content? If so, how would that service advise you? If the service provider provides a web hook or similar callback you could write a server-based program to send a push notification to your Android app.
Perhaps you intent to poll the API periodically, and then you want to know if there is a change?
If you use a tool such as Postman or curl to easily see the headers of the API https://api.afiexplorer.com you will see, unfortunately, there is no Last-Modified header or ETag header which would allow you to easily determine if there was a change.
Next looking at the content of the API, the author does not provide an obvious version/change date, so no luck there.
What you could do is receive the content as a String, and perform a checksum operation on it, and if it differs you know there has been a change
or if you are deserialising the received JSON in Kotlin data classes, then out of the box, Kotlin will enable you to perform an equality operation on a previous copy of the data to know if there was a change.
This looks like an android app; if so, why don't you create a background service that makes requests to the API and updates the data as needed? You can use an AlarmManager class to set the interval threshold for polling by using the setInexactRepeating() method.
Most apps are updated in this fashion; sometimes, a separate table is created to catalog changesets.
Let me know if this helps.
hi
I want to build a control panel for a web art application that needs to run in fullscreen, so all this panel, that controls stuff like colors and speed values, have to be located at a different window.
My idea is to have a database storing all these values and when I make a change in the control panel window the corresponding variable in the application window gets updated too. So, it's basically a real-time update that I could do with AJAX setting a interval to keep checking for changes BUT my problem is: I can't wait 30 seconds or so for the update to happen and I guess a every-1-second AJAX request would be impossible.
Final question: is there a way to create a sort of a listener to changes in the database and fire the update event in the main application only immediately after I change some value in the control panel? Does Angular or another framework have this capability?
(Sorry for the long explanation, but I hope my question is clearer by offering the context [: )
A web socket powered application would have this benefit. This carries a bit more complexity on the back end, but has the benefit of making your application as close to real-time as can be reasonably expected.
The Mozilla Development Network has some good documentation on websockets.
On the front end, the WebSocket object should work for you on most modern browsers.
I'm not sure what your back end is written in, but Socket.IO for Node.js and Tornado for Python will make your applications web-socket capable
If one window is opening the other windows via JavaScript, you can keep the reference to the opened window and use otherWindow.postMessage to pass messages across
"Parent" window looks like
// set up to receive messages
window.addEventListener('message', function (e) {
if (e.origin !== 'http://my.url')
return; // ignore unknown source
console.log(e.message);
});
// set up to send messages
var otherWindow = window.open('/foo', '_blank');
otherWindow.postMessage('hello world', 'http://my.url');
"Child" windows look similar
// same setup to recieve
// ...
// set up to send
var otherWindow = window.opener;
// ... same as before
For the realtime I would recommend using a library like socket.io or using a database like firebase.
For the fullscreen I would recommend using a library like angular-screenfull
i use https://pushjs.io/, had exactly the same problem and this is a really simple solution for your problem. It is capable of sending and listening to events without any database interference.
I've researched and found three different possibilities to solving my case: I'd like to make an async API call (using dotenv variables to store the credentials) and commit the returned data to Vuex on app init --keeping the creds secure.
Currently I'm attempting using serverMiddleware, but I'm having trouble accessing the context. Is this possible? Currently just getting a "store is not defined" error.
Also, after researching, I keep seeing that it's not a good idea to use regular middleware, as running any code on the client-side exposes the env variable... But I'm confused. Doesn't if (!process.client) { ... } take care of this? Or am I missing the bigger picture.
Additionally, if it does turn out to be okay to use middleware to secure the credentials, would using the separate-env-module be wise to make doubly sure that nothing gets leaked client-side?
Thanks, I'm looking forward to understanding this more thoroughly.
You can use serverMiddleware.
You can do it like this:
client -> call serverMiddleware -> servermiddleware calls API.
that way API key is not in client but remains on the server.
Example:
remote api is: https://maps.google.com/api/something
your api: https://awesome.herokuapp.com
since your own api has access to environment variables and you don't want the api key to be included in the generated client-side build, you create a serverMiddleware that will proxy the request for you.
So that in the end, your client will just make a call to https://awesome.herokuapp.com/api/maps, but that endpoint will just call https://maps.google.com/api/something?apikey=123456 and return the response back to you
We are switching our notifications infrastructure to use new GCM 3.0 registration mechanism using Instance ID API. Previously we were using old mechanism using GCMRegistrar.register() method.
The problem we have is that we have noticed that if device was registered with old GCMRegistrar, after update and registering with new Instance ID API, both registration tokens are valid and can receive notifications.
I expected old registration token to be deactivated and that our push server would receive canonical registration ID when sending notification to old token (as described here GCM registering with two different working registration ids), especially that application version has changed, but such case seems not to happen.
Is this correct behavior of GCM? Is there any way we can detect on push server that device received new token (without unregistering from app)?
I have finally received an answer from Google support regarding my issue. It turned out that this was intended behavior:
What you observed is in the intended behavior due to the need to support backward compatible
registration ID.
We recommend you to flag the old registration ID from gcmregistrar() and don't use that to send anymore once you have the registration token from getToken(). (I believe you probably has implemented a solution to detect such)
Our solution was to simply remove old registration tokens from our push server before registering new user.
We did not use GCMRegistrar.unregister() as we observed that it was able to unregister new tokens (obtained via getToken()).
UPDATE:
I just wanted to provide a quick update to anyone interested in this subject.
It seems that this issue was fixed as when we tested our registration mechanism recently, it turned out that new GCM tokens replace (and unregister) old tokens.
Registration token may change upon certain scenarios even going forward. While cononical registration ID is also a good idea. Use tokenRefresh as shown here as well.
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
Suggesting based on this line "it is needed for key rotation and to handle special cases" in method reference.
I am facing to a trouble with 2 adapters based authentication. My app is agenda (hybrid app). All adapter's functions must be protected by security.
my app uses adapters based authentication, like written in samples on DeveloperWorks.
My first adapter (loginAdapter) is dedicated for login (beginning of the mobile app). I developed a handler (handlerLogin, mobile side) with methods isCustomResponse, handlechallenge, etc.. This adapter works.
This adapter allows to get a userId from login and password.
As soon as connected, the user can download his agenda. The mobile calls an other adapter based auth (calendarAdapter). I have an other handler (handlerCalendar) with methods (isCustomResponse, handlechallenge).
When the mobile calls the method getCalendarData (protected method, CalendarAdapter), the server detects that the user is not registered for this adapter, that is why the server send an error (structure authrequired + errorMessage) via the function onAuthRequired.
At this step, all works fine.
Actually, the trouble comes from, that, the first handler (handlerLogin) catches this error, whereas it schould be the second handler (handlerCalendar).
Given that it is catched by the handlerLogin, isCustomResponse and handlechallenge are called, and I do not have the expected result ! I do not know why.
Why it is not catched by the handlerCalendar ?
I verified my code, variable's names, files, etc.. All things are ok.
For informations, I first declared the handlerLogin before the CalendarLogin.
Do you have any ideas, suggestions ??
Thank you in advance
It looks like you used the same realm.
The isCustomResponse function job is to find out if this challenge-handler should take care of this specific request. If you use the same realm for both adapters then the 2 challenge-handlers will react to it.