I've a problem regarding push notifications in worklight 6.2. When I update the os version of a device the deviceId in the worklight console table is updated. Do you know if this is a correct behaviour?
Multiple OS and hardware parameters go into generating the deviceID by Worklight SDK. This means , when there is an OS upgrade the deviceID can change.
If there are no OS changes - upgrade/reset , for the lifetime of an application, the deviceID does not change.
Also, the next time the device connects to the server ( after deviceID change) the server is updated with the new value.
It has not been mentioned if you are passing deviceID directly while dispatching the notification. If so, you should consider using the UserSubscription object to get the device id value.
For example:
notifyDevice
userSubscription = WL.Server.getUserNotificationSubscription ("MyEventSource", userID);
var notification = WL.Server.createDefaultNotification("Hello");
var delayTimeout = WL.Server.notifyDevice( userSubscription, userSubscription.getDeviceSubscriptions()[0].token, notification);
notifyDeviceSubscription
userSubscription = WL.Server.getUserNotificationSubscription ("MyEventSource", userID);
var notification = WL.Server.createDefaultNotification("Hello");
var delayTimeout = WL.Server.notifyDeviceSubscription(userSubscription.getDeviceSubscriptions()[0], notification);
This reduces the possibility of errors due to missing or wrong deviceid as subscriptions are updated when users connect to server. This way, device id stays updated at the server.
Related
I have a NativeScript (Angular) app that makes API-calls to a server to get data. I want to implement a bi-directional synchronization once a device gets online but using current API, no BaaS.
I could do a sort of caching. Once in a while app invalidates info in database and fetches it again. I don't like this approach because there are big lists that may change. They are fetched in batches, i.e. by page. One of them is a list of files downloaded to and stored on a device. So I have to keep those that are still in the list, and delete those that are not. It sounds like a nightmare.
How would you solve such a problem?
I use nativescript-couchebase plugin to store the data. We have following services
Connectivity
Data
API Service
Based on connectivity is Online/Offline, we either fetch data from remote API or via couchebase db. Please note that API service always returns the data from Couchebase only.
So in online mode
API Call -> Write to DB -> Return latest data from Couchebase
Offline mode
Read DB -> Return latest data from Couchebase
Also along with this, we maintain all API calls in a queue. So whenever connectivity returns, API calls are processed in sequence. Another challenge that you may face while coming in online mode from offline mode is the token expiry. This problem can be solved by showing a small popup to user after you come online.
I do this by saving my data as a json string and saving it to the devices file system.
When the app loads/reloads I read it from the file.
ie.
const fileSystemModule = require("tns-core-modules/file-system");
var siteid = appSettings.getNumber("siteid");
var fileName = viewName + ".json";
const documents = fileSystemModule.knownFolders.documents();
const site_folder = documents.getFolder("site");
const siteid_folder = site_folder.getFolder(siteid.toString());
const directoryPath = fileSystemModule.path.join(siteid_folder.path, fileName);
const directoryFile = fileSystemModule.File.fromPath(directoryPath);
directoryFile.writeText(json_string)
.then((result) => {
directoryFile.readText().then((res) => {
retFun(res);
});
}).catch((err) => {
console.log(err.stack);
});
I am facing issues in live environment. When ever a ever a page is loaded signal r connection is created but connectionids of other connects are not available for the new connectionids and also for old connectionId this newly created connection is not available. To make it better understand see the code below
My method in chathub.vb which is called from server side
Public Sub getGonnected()
Clients.Client(Context.ConnectionId).hello("Connection is connected CONNECTIONID = " + Context.ConnectionId)
Dim heartBeat = GlobalHost.DependencyResolver.Resolve(Of ITransportHeartbeat)()
Dim connectionAlive = heartBeat.GetConnections().Where(Function(c) c.ConnectionId <> Context.ConnectionId).ToList()
Clients.Client(Context.ConnectionId).hello("Other Connections Available ..............................................................")
For Each item In connectionAlive
Clients.Client(Context.ConnectionId).hello(".................................................................. " + item.ConnectionId)
Next
Clients.Client(Context.ConnectionId).hello("End of other connections available ........................................................")
Clients.All.hello("Total Number of users available ..................................................................")
Clients.All.hello("........................................................................... " + connectionAlive.Count().ToString())
Clients.All.hello("End total Number of users available ...............................................................")
End Sub
And in my clients side
chat.client.hello = function(ping)
{
console.log(ping);
}
$.connection.hub.start().done(function () {
});
setInterval(function () {
chat.server.getGonnected().done(function (result) {
console.log('connectionRequestsent')
});
}, 5000);
Also in my web.config I have added following settings
target framework 4.5
As per above example code above
I am not able to see a new connection in the borwsers console when some new user registers will signalr. And also that new user is unable to see the ConnectionId's of already present users in signalr in the browser console.
This thing is only happening on server. An help would be much appretiated. I have already enabled websockets and my websockets handshake is successfull. Moreover the spefic conntectionId is able to send and recieve messages to and from server. But not with other connectionId as the are not availble.
In simple words some times
Dim connectionAlive = heartBeat.GetConnections().Where(Function(c)
c.ConnectionId <> Context.ConnectionId).ToList()
Length is 0 where as there are already other connections in the app. Which I am not sure why is happening.
Any help or guidance will be much appreciated.
SignalR version is 2.1.0
Regards
Abdul
I don't think this has anything to do with WIndows Server 2012. You will have to implement this yourself in either a dictionary, database or something else suitable to your situation.
Using the OnConnect event, you can broadcast to every currently connected client an update that someone has joined or with the OnDisconnect that someone has left as well. If you want it to be a list of currently connected users you would query your dictionary/database/else... and broadcast.
SignalR Documentation has some examples.
Download working signalr project at https://github.com/aspnet/SignalR-samples from the developer
After downloading select any of the examples in the directory which you will run through your visual studio.
I select ChatSample run and follow the on-screen instruction
After that go through the documentation to read through each files how it works at
https://learn.microsoft.com/en-us/aspnet/core/signalr/
Please install the latest version of .Net Framework, in my case this solve the problem, I installed 4.8 and all broadcast messages were sent.
I'm converting my Windows Phone 8 Silverlight to UWP and I can't find an equivalent to DeviceNetworkInformation.NetworkAvailabilityChanged event in UWP
I know that on UWP we have to use ConnectionProfile to get info about user's connection (Wifi, 3G, etc...)
ConnectionProfile InternetConnectionProfile = NetworkInformation.GetInternetConnectionProfile();
But it seems that there are no events to check if the Internet becomes unavailable in ConnectionProfile object.
Does anyone know how to do this in UWP?
Thanks
There might be no equivalent of DeviceNetworkInformation.NetworkAvailabilityChanged Event in UWP APIs by now. But we can achieve this by combining NetworkInformation.NetworkStatusChanged event with ConnectionProfile.GetNetworkConnectivityLevel method.
Ref Remarks in ConnectionProfile.GetNetworkConnectivityLevel:
The recommended process for determining the network connectivity level is to register a handler for the NetworkStatusChanged event on the NetworkInformation class. When a notification is received of a network status change, obtain the new connectivity level by calling the GetNetworkConnectivityLevel method on the profile returned by the GetInternetConnectionProfile method. The returned network connectivity level can then be stored for later use when needed. This also ensures that the correct ConnectionProfile is checked.
Following is a simple sample:
NetworkInformation.NetworkStatusChanged += (s) =>
{
var profile = NetworkInformation.GetInternetConnectionProfile();
var isInternetConnected = profile != null && profile.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess;
};
Also you can encapsulate this into an event like in this blog: How to react to network availability changes in Windows Store apps.
I have Wp8.1 Silverlight app that receives push notification (WNS) from Mobileservice (the old azure service).
I therefore wanted to update to the new service because of the new features. I have now created/upgraded a new server to use App Service - Mobile App. And tested push notification with the sample app from azure (everything works).
Going back to my app WP8.1 -> Adding the new package Microsoft.Azure.Mobile.Client through NuGet (2.0.1), there is the issue that the Microsoft.WindowsAzure.Mobile.Ext does not contain the 'GetPush' extension. It seems like it is missing it? looking to the WP8 version, it only registers to MPNS, and I need WNS. So I do not know if any other assembly could be used.
Can I add another assembly reference?
Update
The following code lets me register the device on the server, and I can see the device register correctly. where the channelUri and the installationInformation are retrieved by the client and send to the server.
Installation ins = new Installation();
ins.Platform = NotificationPlatform.Wns;
ins.PushChannel = uTagAndChan.ChannelUri;
ins.Tags = uTagAndChan.Tags;
ins.InstallationId = uTagAndChan.installationInformation;
await hubClient.CreateOrUpdateInstallationAsync(ins);
Sending a test toast-notification to the registered tags, results in the following error :
The Token obtained from the Token Provider is wrong
Searching on this issue I found Windows Store App Push Notifications via Azure Service Bus. Which the proposed solution says to register to the notification hub directly from the app, I would rather not have the app to have directly access to the hub. But is this the only way? (mind you the answer was not accepted, but I will try it all though it is not a desired solution)
Update
Registering for notifications via client (WP8.1 Silverligt), makes a registration to MPNS, which I do not want.
The snippet on the server registers a WNS, the two registrations can be seen here:
The URI retrieval is done using
var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
which in the description states it returns a WNS. This seems to infer that the registration I am doing on the server (code snippet in the top) is correct and the registration on the client is faulty.
But the registration on the image seems wrong. Shouldn't the PNS Identifier be different for the two registrations? also expiration date seems wrong ?
How to mend this since the GetPush() (which was available in the sample registered the client correctly for notifications) does not exist in the NuGet package?
Update
I read one place that deleting and recreating the NotificationHub could help. I will try this today. Even IF it works, it would be more desirable to have the solution, and to know if the registrations are done correctly?
Temporary solution:
Deltede, recreated, inserted Package SID and Secret. And it works again (strange)!
Still interested in the underlying issue!
Deleted and recreated the service, setting all the same settings made it work again.
I had same issue with my UWP. But in my case I had issue with self signed certificate.
When I set the AppxPackageSigningEnabled property to True (in .csproj) then notifications stopped working and I got "The token obtained from the Token Provider is wrong" (Test send from Azure Portal).
The certificate must have same issuer as Publisher in Identity element in .appxmanifest file.
I am using Azure Notification Hubs to deliver push notifications to an android/iPhone devices.
My general flow is:
1.Every time the user opens the mobile app, a call is made to the PNS
(APNS/GCM) and gets an updated device token.
2. The device token is then sent to the server.
3. The server executes the following code to register the token:
RegistrationDescription reg;
if (deviceType == DeviceType.Iphone)
{
reg = new AppleRegistrationDescription(deviceToken, new string[] { userId.ToString() });
}
else
{
reg = new GcmRegistrationDescription(deviceToken, new string[] { userId.ToString() });
}
reg = await hub.CreateRegistrationAsync(reg);
It works great, but my question is, should I be tracking those device tokens in my server for some reason? For example save them in a table for later use or other scenarios I could be facing, or it's intended to use that way(without saving them in a table).
Your code creates a lot of duplicates, by duplicate I mean different registrations with same PNS handle (APNS device token or GCM registration id). NH has de-duplication logic which prevents your devices from receiving multiple copies of same message, but it increases internal storage space and slows system down.
So there is recommendation:
On each device your create and store some GUID-like identifier;
You pass that identifier on server together with PNS handle;
On server you do hub.GetRegistrationByTagAsync(deviceGuid, 100);
If registration returned, then update it with received PNS handle
(even if PNS handle the same - just to prevent expiration);
If result is empty, then you create new registration specifying device GUID as a tag;
Also there is new API which allows you to do only one call and not use any tags if you don't need them. https://msdn.microsoft.com/en-us/magazine/dn948105.aspx Look at topic Case 2: The Back End Manages Devices in Notification Hubs. It is not very good explanation maybe but feature is new. If any questions about that API then I can answer.