I try to send iOS push notifications using pushsharp library but I got
the maximum send attempts was reached
This is my code (note that I'm implementing pushbroker event function but I'm not showing it here):
public class PushNotificationApple
{
private static PushBroker _pushBroker;
public PushNotificationApple()
{
if (_pushBroker == null)
{
//Create our push services broker
_pushBroker = new PushBroker();
_pushBroker.OnNotificationSent += NotificationSent;
_pushBroker.OnChannelException += ChannelException;
_pushBroker.OnServiceException += ServiceException;
_pushBroker.OnNotificationFailed += NotificationFailed;
_pushBroker.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
_pushBroker.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
_pushBroker.OnChannelCreated += ChannelCreated;
_pushBroker.OnChannelDestroyed += ChannelDestroyed;
PushBroker broker = new PushBroker();
string certpass = "XXXXXX.";
var appleCert = File.ReadAllBytes("c:\\certifIOS\\Certificates.p12");
_pushBroker.RegisterAppleService(new ApplePushChannelSettings(false, appleCert, certpass)); //Extension method
}
}
public void SendNotification(string deviceToken, string message)
{
//Fluent construction of an iOS notification
//IMPORTANT: For iOS you MUST MUST MUST use your own DeviceToken here that gets generated within your iOS app itself when the Application Delegate
// for registered for remote notifications is called, and the device token is passed back to you
if (_pushBroker != null)
{
AppleNotification appnotif = new AppleNotification() ;
_pushBroker.QueueNotification(appnotif
.ForDeviceToken(deviceToken)//the recipient device id
.WithAlert(message)//the message
.WithBadge(1)
.WithSound("default")
);
bool v = appnotif.IsValidDeviceRegistrationId();
_pushBroker.StopAllServices(true);
}
}
}
Most likely the connections to apple push gateways are blocked,please try to use telnet:
telnet gateway.push.apple.com 2195
telnet gateway.sandbox.push.apple.com 2195
make sure they are not blocked
Related
In my windows forms app I am starting to enumerate list of devices as follows:
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
// Register event handlers before starting the watcher.
// Added, Updated and Removed are required to get all nearby devices
deviceWatcher.Added += DeviceWatcher_Added;
// EnumerationCompleted and Stopped are optional to implement.
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
// Start the watcher.
deviceWatcher.Start();
when a device is found I am retrieving the service and characteristic as follows:
BluetoothLEDevice btdev;
List<DeviceInformation> lst = new List<DeviceInformation>();
GattCharacteristic ch;
private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
{
if (args.Name == "Bluno")
{
btdev = await BluetoothLEDevice.FromIdAsync(args.Id);
GattDeviceServicesResult result = await btdev.GetGattServicesAsync();
Guid customGuid = new Guid("0000dfb0-0000-1000-8000-00805f9b34fb");
foreach (GattDeviceService service in result.Services)
{
if (customGuid == service.Uuid)
{
GattCharacteristicsResult cresult = await service.GetCharacteristicsAsync();
ch = cresult.Characteristics.Where(x => x.Uuid == new Guid("0000dfb1-0000-1000-8000-00805f9b34fb")).FirstOrDefault();
ch.ValueChanged += Ch_ValueChanged;
}
}
}
}
the issue is that it is not firing the ValueChanged event even if the BLE device continuously sending multiple values per second.
help appreciated
I would like to keep on reading characteristic/set value changed event handlers for characteristics from my BLE 4.0 device, by using the ValueChanged callback in Universal Windows Platform C# in Visual Studio 2017.
I followed some tutorial from these sites: Damian Blog's Windows Universal with BLE, Bluetooth Gatt's Git Hub, Bluetooth Generic Attribute Profile - Heart Rate Service and Dr. Jukka's mobile Blog on BLE. All of them are using ValueChanged and I have tried to follow what they did.
Unfortunately, instead of ValueChanged being triggered, I receive the following error when using the ValueChanged callback.
System.ArgumentException: 'Value does not fall within the expected range.'
This line of code is producing the error:
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
Here is more details of my source code:
NOTE: I am using COM 7 for my dongler and my program could discover the BLE's device name, and could discover the Uuid of the services and characteristics.
public List<string> serviceList = new List<string>();
public List<string> characteristicList = new List<string>();
public BluetoothLEDevice myDevice { get; set; }
public MainPage()
{
this.InitializeComponent();
}
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
// Find the com port
string selector = SerialDevice.GetDeviceSelector("COM7");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(selector);
if (devices.Count > 0)
{
var dialog = new MessageDialog("Com Device found");
await dialog.ShowAsync();
DeviceInformation deviceInfo = devices[0];
SerialDevice serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
serialDevice.BaudRate = 9600;
serialDevice.DataBits = 8;
serialDevice.StopBits = SerialStopBitCount.One;
serialDevice.Parity = SerialParity.None;
}
else
{
MessageDialog popup = new MessageDialog("Sorry, no device found.");
await popup.ShowAsync();
}
// After com port is found, search for device
foreach (DeviceInformation di in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()))
{
BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(di.Id);
// Display BLE device name
var dialogBleDeviceName = new MessageDialog("BLE Device Name " + bleDevice.Name);
await dialogBleDeviceName.ShowAsync();
myDevice = bleDevice;
}
// Check device connection
myDevice.ConnectionStatusChanged += OnConnectionStatusChanged;
foreach (var service in myDevice.GattServices)
{
serviceList.Add(service.Uuid.ToString());
// Verify if service is discovered by displaying a popup
MessageDialog serviceUuidPopUp = new MessageDialog("Adding Service Uuid to list " + service.Uuid.ToString() );
await serviceUuidPopUp.ShowAsync();
foreach (var characteristic in service.GetAllCharacteristics())
{
var characteristicUuid = characteristic.Uuid.ToString().ToLowerInvariant();
characteristicList.Add(characteristicUuid);
// Verify if characteristic is discovered by displaying a popup
MessageDialog charUuidPopUp = new MessageDialog("Adding characteristic Uuid to list " + characteristicUuid);
await charUuidPopUp.ShowAsync();
// set value changed event handlers for characteristics
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
}
}
}
private void OnConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
if (sender.ConnectionStatus == BluetoothConnectionStatus.Connected)
{
System.Diagnostics.Debug.WriteLine("Connected");
}
else
{
System.Diagnostics.Debug.WriteLine("Disconnected");
}
}
private void Oncharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] data = new byte[args.CharacteristicValue.Length];
DataReader.FromBuffer(
args.CharacteristicValue).ReadBytes(data);
string text = Encoding.UTF8.GetString(data, 0, data.Length);
}
UPDATE 1
I tried to check Characteristic Properties before set value changed event handlers for my characteristics by following the answer given by rudi belt on SO.
if (characteristic.CharacteristicProperties == (GattCharacteristicProperties.Read | GattCharacteristicProperties.Notify))
{
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
}
Unfortunately, this IF statement is not executed.
UPDATE 2
I have tried to remove ALL the codes inside Oncharacteristic_ValueChanged method. But it still gives me the same error
System.ArgumentException: 'Value does not fall within the expected range.'
I have been spending a lot of time trying to solve this problem. I will be very happy if anyone can help me on this. Thank you!
Reading your efforts in the former question I can provide a working example, but first some explanation.
myDevice.ConnectionStatusChanged is not needed, it is only used to notice a connection is lost or connected. You have to connect to your device first and handle things in the connection method.
After you have succeeded in connecting you have to get the service that contains the characteristic you want to use for read, write, notify or indicate.
When you have selected the service You can get the characteristics of that service.
Select the characteristic by Uuid, or in my example with CharacteristicProperties.HasFlag.
This flag in my example is Notify.
In the code comments you find extra info.
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.UI.Popups;
using Windows.UI.Xaml.Controls;
namespace App1
{
public sealed partial class MainPage : Page
{
GattDeviceServicesResult serviceResult = null;
private BluetoothLEDevice myDevice;
private GattCharacteristic selectedCharacteristic;
public MainPage()
{
this.InitializeComponent();
ConnectDevice();
}
private async void ConnectDevice()
{
//This works only if your device is already paired!
foreach (DeviceInformation di in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()))
{
BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(di.Id);
// Display BLE device name
var dialogBleDeviceName = new MessageDialog("BLE Device Name " + bleDevice.Name);
await dialogBleDeviceName.ShowAsync();
myDevice = bleDevice;
}
if (myDevice != null)
{
int servicesCount = 3;//Fill in the amount of services from your device!!!!!
int tryCount = 0;
bool connected = false;
while (!connected)//This is to make sure all services are found.
{
tryCount++;
serviceResult = await myDevice.GetGattServicesAsync();
if (serviceResult.Status == GattCommunicationStatus.Success && serviceResult.Services.Count >= servicesCount)
{
connected = true;
Debug.WriteLine("Connected in " + tryCount + " tries");
}
if (tryCount > 5)//make this larger if faild
{
Debug.WriteLine("Failed to connect to device ");
return;
}
}
if (connected)
{
for (int i = 0; i < serviceResult.Services.Count; i++)
{
var service = serviceResult.Services[i];
//This must be the service that contains the Gatt-Characteristic you want to read from or write to !!!!!!!.
string myServiceUuid = "0000ffe0-0000-1000-8000-00805f9b34fb";
if (service.Uuid.ToString() == myServiceUuid)
{
Get_Characteriisics(service);
break;
}
}
}
}
}
private async void Get_Characteriisics(GattDeviceService myService)
{
var CharResult = await myService.GetCharacteristicsAsync();
if (CharResult.Status == GattCommunicationStatus.Success)
{
foreach (GattCharacteristic c in CharResult.Characteristics)
{
if (c.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify))
{
selectedCharacteristic = c;
break;
}
}
try
{
// Write the ClientCharacteristicConfigurationDescriptor in order for server to send notifications.
var result = await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(
GattClientCharacteristicConfigurationDescriptorValue.Notify);
if (result == GattCommunicationStatus.Success)
{
var dialogNotifications = new MessageDialog("Successfully registered for notifications");
await dialogNotifications.ShowAsync();
selectedCharacteristic.ValueChanged += SelectedCharacteristic_ValueChanged;
}
else
{
var dialogNotifications = new MessageDialog($"Error registering for notifications: {result}");
await dialogNotifications.ShowAsync();
}
}
catch (Exception ex)
{
// This usually happens when not all characteristics are found
// or selected characteristic has no Notify.
var dialogNotifications = new MessageDialog(ex.Message);
await dialogNotifications.ShowAsync();
await Task.Delay(100);
Get_Characteriisics(myService); //try again
//!!! Add a max try counter to prevent infinite loop!!!!!!!
}
}
else
{
var dialogNotifications = new MessageDialog("Restricted service. Can't read characteristics");
await dialogNotifications.ShowAsync();
}
}
private void SelectedCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
}
}
}
If you have problems with this code feel free to ask in comments.
Afternoon all,
I have a windows service which subscribes to an Office365 email account and awaits new emails, when they arrive it processes their attachments, and all is well with the world.
But... for some reason, the applications stops receiving notifications after an undetermined amount of time.
I have handled the 'OnDisconnect' event and reestablish a connection as shown in the below code, but that doesnt seem to be fixing this issue. The windows service continues to run fine, and if I restart the service everything is good again, until is failed again.
This is the my class for running exchange:
public class ExchangeConnection
{
static readonly ExchangeService Service = Exchange.Service.ConnectToService(UserDataFromConsole.GetUserData(), new TraceListener());
public event EmailReceivedHandler OnEmailReceived;
public ExchangeConnection()
{
}
public void Open()
{
SetStreamingNotifications(Service);
var signal = new AutoResetEvent(false);
signal.WaitOne();
}
private void SetStreamingNotifications(ExchangeService service)
{
var streamingsubscription = service.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Inbox }, EventType.NewMail);
var connection = new StreamingSubscriptionConnection(service, 30);
connection.AddSubscription(streamingsubscription);
connection.OnNotificationEvent += OnEvent;
connection.OnSubscriptionError += OnError;
connection.OnDisconnect += OnDisconnect;
connection.Open();
}
public void MoveEmail(ItemId id, String folderName = "Archived Emails")
{
var rootFolder = Folder.Bind(Service, WellKnownFolderName.Inbox);
var archivedFolder = rootFolder.FindFolders(new FolderView(100)).FirstOrDefault(x => x.DisplayName == folderName);
if (archivedFolder == null)
{
archivedFolder = new Folder(Service) { DisplayName = folderName };
archivedFolder.Save(WellKnownFolderName.Inbox);
}
Service.MoveItems(new List<ItemId> {id}, archivedFolder.Id);
}
#region events
private void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
//The connection is disconnected every 30minutes, and we are unable to override this,
//so when we get disconnected we just need to reconnect again.
var connection = (StreamingSubscriptionConnection)sender;
connection.Open();
}
private void OnEvent(object sender, NotificationEventArgs args)
{
var subscription = args.Subscription;
// Loop through all item-related events.
foreach (var notification in args.Events)
{
switch (notification.EventType)
{
case EventType.NewMail:
if (notification is ItemEvent)
{
var email = Item.Bind(Service, new ItemId(((ItemEvent) notification).ItemId.UniqueId));
OnEmailReceived(new EmailReceivedArgs((EmailMessage)email));
}
break;
}
}
}
private void OnError(object sender, SubscriptionErrorEventArgs args)
{
var e = args.Exception;
Logger.LogException(e,LogEventType.Error);
}
#endregion events
}
Any help would be great, thanks.
EDIT:
After improving the error logging I have found this exception occuring:
Exception: The specified subscription was not found.
Any ideas what is causing this?
With Office365 you need to make sure you deal with affinity see http://msdn.microsoft.com/en-us/library/office/dn458789(v=exchg.150).aspx . Adding those headers will ensure your requests will always routed to the correct servers.
Cheers
Glen
The server listener class starts to accept incoming connections from all IP's:
while (true)
{
CommandManager cm = new CommandManager(s.Accept());
}
public CommandManager(Socket clientSocket)
{
this.socket = clientSocket;
this.networkStream = new NetworkStream(this.socket);
this.bwReceiver = new BackgroundWorker();
this.bwReceiver.DoWork += new DoWorkEventHandler(StartReceive);
this.bwReceiver.RunWorkerAsync();
}
private void StartReceive(object sender, DoWorkEventArgs e)
{
while (this.socket.Connected)
{
string s = dataStr.Substring(10);
Command c = JsonConvert.DeserializeObject<Command>(s);
CommandHandler.HandleCommand(c, clientIP, this.socket);
this.networkStream.Flush();
}
}
CommandHandler does different things depending on the command, and when a command is received (from a Corona SDK app) everything works great. The problem is when I need to send back a message after receiving a message.
First, if a player logs in I save that communication info in Communication class which saves the socket information:
Player.Player p = new Player.Player(cmd.PlayerID);
p.Communication = new ClientCommunication(clientSocket);
However if the command is "UpdateTable" I also need to send back the Table information to all the active players and this is where the problem occurs:
if (cmd.Cmd = Command.UpdateTable)
{
//Do the updates
//Send back the updates to the players
Command c = new Command();
c.Cmd = Commands.ReceiveTables;
c.Tables = new List<Table.Table>();
Table.Table t = Table.TableManager.ReturnTable(cmd.Table.TableID);
c.Tables.Add(t);
string command = JsonConvert.SerializeObject(c);
command = command + Environment.NewLine;
foreach (Table.Seat seat in t.Players)
{
try
{
Communication.ClientCommunication com = Player.PlayerManager.GetCommunication(seat.Player.PlayerID);
Socket client = com.ReturnSocket();
client.Send(Encoding.ASCII.GetBytes(command));
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.ToString());
}
}
}
I have verified that in client.Send() the port and IP as correct but I only receives a message back to the original sender (i.e. the player that sent in the messages receives the message but the other player(s) doesn't receive anything from the client.Send()).
I am using SocketIO4Net to create a .NET socket.io client in my worker role with which i can connect to my socket.io server. I have been able to connect to the namespace after shifting around a lot of code than what was mentioned in the documentation. But I am still not able to send and receive messages to events. Below is my code, please let me know how I can register events to the socket.io .net client. Its really important for my project that i am able to send messages to socket.io server events from my worker role.
broadcastSocketClient = new Client(localSocketUrl);
broadcastSocketClient.Opened += SocketOpened;
broadcastSocketClient.Message += SocketMessage;
broadcastSocketClient.SocketConnectionClosed += SocketConnectionClosed;
broadcastSocketClient.Error += SocketError;
while (!broadcastSocketClient.IsConnected)
{
broadcastSocketClient.Connect();
}
// register for 'connect' event with io server
broadcastSocketClient.On("connect", (cn) =>
{
var namespaceConnect = broadcastSocketClient.Connect("/namespacename");
// register for 'connect' event with io server
namespaceConnect.On("connect", (data) =>
{
namespaceConnect.Emit("test", "CONNECTED");
namespaceConnect.On("first", (message) =>
{
Console.WriteLine(message);
});
});
});
This is a very similar question to https://stackoverflow.com/a/16002007/1168541, but one area that's going to give you trouble is in your code to connect:
while (!broadcastSocketClient.IsConnected)
{
broadcastSocketClient.Connect();
}
You should wait for the event message 'connected', rather than blast multiple connection attempts. You'll never give the client the chance to connect in the while loop.
Try something along these lines:
public class SampleClient
{
private Client socket;
private IEndPointClient nsTarget;
private string localSocketUrl = "http:your_url_to_socketioserver";
public void Execute()
{
Console.WriteLine("Starting SocketIO4Net Client Events Example...");
socket = new Client(localSocketUrl);
socket.Opened += SocketOpened;
socket.Message += SocketMessage;
socket.SocketConnectionClosed += SocketConnectionClosed;
socket.Error += SocketError;
// register for 'connect' event with io server
socket.On("connect", (fn) =>
{ // connect to namespace
nsTarget = socket.Connect("/namespacename");
nsTarget.On("connect", (cn) => nsTarget.Emit("test", new { data = "CONNECTED" }));
nsTarget.On("first", (message) =>
{
Console.WriteLine("recv [socket].[update] event");
Console.WriteLine(" raw message: {0}", message.RawMessage);
Console.WriteLine(" string message: {0}", message.MessageText);
Console.WriteLine(" json data string: {0}", message.Json.ToJsonString());
});
});
// make the socket.io connection
socket.Connect();
}
void SocketOpened(object sender, EventArgs e)
{
Console.WriteLine("SocketOpened\r\n");
Console.WriteLine("Connected to ICBIT API server!\r\n");
}
void SocketError(object sender, ErrorEventArgs e)
{
Console.WriteLine("socket client error:");
Console.WriteLine(e.Message);
}
void SocketConnectionClosed(object sender, EventArgs e)
{
Console.WriteLine("WebSocketConnection was terminated!");
}
void SocketMessage(object sender, MessageEventArgs e)
{
// uncomment to show any non-registered messages
if (string.IsNullOrEmpty(e.Message.Event))
Console.WriteLine("Generic SocketMessage: {0}", e.Message.MessageText);
else
Console.WriteLine("Generic SocketMessage: {0} : {1}", e.Message.Event, e.Message.Json.ToJsonString());
}
public void Close()
{
if (this.socket != null)
{
socket.Opened -= SocketOpened;
socket.Message -= SocketMessage;
socket.SocketConnectionClosed -= SocketConnectionClosed;
socket.Error -= SocketError;
this.socket.Dispose(); // close & dispose of socket client
}
}
}