I'm trying to set up push notifications for a browser web app.
I found the following code can be used to subscribe to a push server. Running a simple push server locally seems to work fine, but
Q: I was wondering how I would specify the push server if it wasn't local?
I mean, how would the browser know where to subscribe to just by looking at the public key of the server?
function createNotificationSubscription(pushServerPublicKey) {
return navigator.serviceWorker.ready.then(
(serviceWorker) => {
return serviceWorker.pushManager
.subscribe({
userVisibleOnly: true,
applicationServerKey: pushServerPublicKey
})
.then((subscription) => {
console.log("✅ User is subscribed.", subscription);
return subscription;
});
}
);
}
References:
https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe
how do I specify the push server [...]?
You don't.
if it wasn't local?
There is a misunderstanding.
The push server will always be a fixed server given by the browser vendor.
It basically works like this:
You subscribe()
This request goes to the notification server of the browser vendor (mozilla, google, ...).
That server will create a so called push endpoint - just a fancy word for URL. This URL serves as a mailbox: If someone sends a message to it, the push server (still being the server of the browser vendor) will forward it to the browser (client).
The server will return the push endpoint and some other information as a result of your initial subscribe().
Currently only the push server and your web app know about the push endpoint....
So your web app needs to the whole result of subscribe to the application server (which is your server).
Now your server is able to use that information to send messages to the push server. The push server will then forward the message to the client.
Here's also a flow chart depicting the flow with a little more detail in regard of the different players:
Push service: Service running on the browser vendor's server
Subscription information: URL of the push endpoint along with some keys.
Related
There is a very good utility called ttyd, which allows you to run a console application on your computer and display this console in the browser.
After startup, the utility starts an http web server on the specified port and when accessing localhost, a website with a web application that connects using web sockets to localhost:<port>/ws, and already with the help of them there is communication between the web application and the ttyd agent running on the computer.
I want to implement a client for ttyd in c#. I studied with the help of chrome tools what data the web application sends before receiving the data output to the console. This is just a string: {"authToken":"","columns":211,"rows":46} and tried to repeat the same actions in the c# client. But for some reason, no data from ttyd is returned to me.
Comparing the data output by ttyd to its console in the OS itself, it can be seen that it does not even create a process when accessing from my client.
Here is the code I use with the Websocket.Client package
var exitEvent = new ManualResetEvent(false);
var url = new Uri("ws://localhost:7681/ws");
using (var client = new WebsocketClient(url))
{
client.ReconnectTimeout = TimeSpan.FromSeconds(30);
client.ReconnectionHappened.Subscribe(info =>
Console.WriteLine($"Reconnection happened, type: {info.Type}"));
client.MessageReceived.Subscribe(msg => Console.WriteLine($"Message received: {msg}"));
client.Start();
Task.Run(() => client.Send("{\"AuthToken\":\"\",\"columns\":211,\"rows\":46}"));
exitEvent.WaitOne();
}
I have absolutely no idea how to get ttyd to send data to my client. Do you have any idea what action the browser is doing I'm missing in my c# client?
I tried different libraries for web sockets in c#, and also used postman with copying all the headers that the original web application sends to the ttyd agent, but this does not change anything. That is, ttyd, something is fundamentally interfering, as if my web client is not doing something that the browser is doing.
Example:
Schedule a notification for 15 minutes and save the user's location.
If the user leaves radius, the notification will not be sent.
Would it be possible to do this using onesignal or just with cordovaLocalNotification?
var notificationObj = {
contents: {
en: "asdasdasd"
},
include_player_ids: [playerId],
send_after: "2017-02-15 20:42:00 GMT-0200",
}
window.plugins.OneSignal.postNotification(notificationObj,
function(successResponse) {
console.log("Notification Post Success:", successResponse);
},
function (failedResponse) {
console.log("Notification Post Failed: ", failedResponse);
alert("Notification Post Failed:\n" + JSON.stringify(failedResponse));
}
)
})
Before that I would save the current location and at the time of sending I would compare if the location is within the 1km radius. If yes, I would send it if not, I would not send
There are two types of notifications: local notifications and push notifications.
Local notifications work like an alert (i.e. I want to be awaked at 9AM) and they can be saved and launched locally, without any internet connection, at the specified time. For this kind of notifications, you can use the Local Notifications plugin.
The second case, Push Notifications, are sent (basically...) from your server to the user app via internet suitably a kind of notification rules set server side.
So, for you specific case, if I got your needs, you can:
get your actual location and timing, send all these data to your server
save (server side) these data and set a timing (15 mins) to send a push notification
after 15 mins, without info from the client app, send the push notitication.
If the user leave the circle radius, send a message to your server, telling "I'm out of the circle, don't send me the push notification". You can decide, server side, to stop the further notification sending.
So, for your case, I would just use Push Notifications.
Little drawback: if the user looses connection and leaves the circle, the client message would not be sent to the server and the server would not be alerted about that, so it'll send the notification to the user. Anyway you can manage, client side, this case to avoid it.
Edit: you can also manage everything using Local Notifications as alerts and don't use Push Notifications at all, as you wish. I would not use both systems.
I made a function to check if someone is logged in on the site in the user controller module:
exports.isLoggedIn = function(req, res, next) {
if (req.user) {
return true;
} else {
return false;
}
};
I have no idea how I want to use this in a imported script on the client side. I couldn't find a good solution on the web so I thought I would ask the question myself.
If I import the script in the .html I get an error that says it doesnt know the require() function that node has.
I hope someone can help me :)
If you want client access to some data that is only available on the server, then you need to send an ajax call from the client to your server and you need to create a route on your server to respond to that ajax call.
Client code runs only on the client and has no direct access to any data on the server.
Server code runs only on the server and has no direct access to any data on the client.
To communicate between the two, you have to send a request from one to the other and then return a response. Usually this is done with an Ajax call sent from client to server. You could also establish a webSocket connection between the two and then either client or server could send data to the other.
The server also has the opportunity, when creating the original page content, to embed settings or values in the page itself, either as Javascript variables, as HTML values or even as a cookie. This obviously has to be done ahead of time when the page is rendered so it can't be a request that the client comes up with later after the page has been rendered to the client.
FYI, in the particular example you show, it is common for a client to be able to tell if it is logged in via some state in the page (either the presence of a particular cookie) or something else embedded in the page by the server. This isn't necessarily secure and isn't the way the server would tell if a request was logged in, but it usually suffices for client-side logic to decide how it wants to behave.
I am learning Node.js. While creating a web site, I will run the web site locally (on localhost). When it is deployed, it will run on other servers. My question is, how do I determine if a request is from localhost or not in Node? In ASP.NET, I could use Request.IsLocal. I'm trying to figure out how to do that in Node.
Thank you!
There's server.address() to get the server address.
And request has connection and socket objects, as both might hold remote address (in a remoteAddress property) depending on a type of current connection.
But if the server is behind a reverse proxy, you'll have to pull it from appropriate header, most likely x-forwarded-for. However I'm not sure if that holds if proxies are chained.
So, to conclude, you'd do something along the lines of:
function cliAddress(req) {
return req.connection.remoteAddress || req.socket.remoteAddress || req.headers['x-forwarded-for'];
}
server.isLocal = function(request) {
return server.address() === cliAddress(req);
}
And if you use express.js see Express.js Req.IP API.
I made a simple chat app. I am impressed by signalR.
My question is, does this technology give us an ability to call asp.net server side methods (for example ones in aspx.cs backend) ?
Let me explain you what I am talking about. I have a WCF service which retrieves data from database and sends it to client. On client side, there is a method getCars(), which is called on page_Load and shows all cars to the user.
But for example if other client changes the cars and sends changes to WCF service, service updates new data to database. So is there an option to get this changes shown to other people with SignalR..
Like normal SignalR sendMessage works.. Some client sends message to server, and server adds message to all clients, is there a possibility to to the same with ASP.NET method for ALL clients with signalR (when one client invokes changes in database to call that method again fro ALL clients)?
I heard this is done with Duplex with WCF but I am interested if it is possible with SignalR?
Yes you can, since you are using the JavaScript client, when the client do a change you call the server
commandHubProxy.invoke('InformClients').done(function (result) {
//Call Succeeded
}).fail(function (error) {
//log error
});
And on the server, the method informs the rest of the clients
public void InformClients(string text)
{
Clients.Others.DataUpdated();
}
Then on the other clients you can do an Ajax request to refresh the data
commandHubProxy.on('DataUpdated', function () {
//Refresh the data or inform the user
});