mqtt publisher not working in xamarin ios - c#

i'm trying to make an android / ios app that publishes mqtt messages to a local server i'm using MQTTNET.
The Android version is working fine but when i try to run it on the ios one it just dosen't work
public async Task connect(string channel,string message)
{
try
{
var mqttFactory = new MqttFactory();
IMqttClient client = mqttFactory.CreateMqttClient();
var options = new MqttClientOptionsBuilder().WithClientId(Guid.NewGuid()
.ToString()).WithTcpServer("192.168.1.68").WithCleanSession().Build();
client.UseConnectedHandler(e =>
{
Console.WriteLine("connected to the server");
client.SubscribeAsync(new TopicFilterBuilder().WithTopic(channel).Build());
});
client.UseDisconnectedHandler(e =>
{
Console.WriteLine("disconnected to the server");
});
await client.ConnectAsync(options);
await PublishMessageAsync(client, message, channel);
await client.DisconnectAsync();
}catch (Exception ex)
{
var o = ex.Message.ToString();
}
}
static async Task PublishMessageAsync(IMqttClient client,string payload,string topic)
{
string messagePayload = payload;
var message = new MqttApplicationMessageBuilder().WithTopic(topic)
.WithPayload(messagePayload)
.WithAtLeastOnceQoS().Build();
if (client.IsConnected)
{
await client.PublishAsync(message);
}
}
No error is shown, the debugger stops at client.connectAsync().

Related

Task is canceled randomly on Linux Server

I ran into the following problem: I start a task to process responses from a bot in a telegram for a long execution
Task.Factory.StartNew(() => _.RunAsync(), TaskCreationOptions.LongRunning)
_ - is an instance of my service
method code below:
/// <inheritdoc />
public async Task RunAsync()
{
// запуск метода рассылки пользователям сообщений со стоимостями их портфелей
await _notifier.RunAsync(_cancellationTokenSource.Token);
var updateReceiver = _telegramClient.GetUpdateReceiver(
new[]
{
UpdateType.Message,
UpdateType.CallbackQuery,
});
try
{
Logger.Info("Revaluate portfolios service successfully launched!");
await foreach (var update in updateReceiver.WithCancellation(_cancellationTokenSource.Token))
{
var updateModel = new UpdateModel()
{
Text = update.Message?.Text ?? update.CallbackQuery?.Data,
ChatId = update.Message?.Chat.Id ?? update.CallbackQuery?.Message?.Chat.Id ?? 0,
Phone = update.Message?.Contact?.PhoneNumber ?? "",
From = update.Message?.From ?? update.CallbackQuery?.From
};
await HandleMessageAsync(updateModel);
}
}
catch (OperationCanceledException exception)
{
Logger.Error(exception, "The service was stopped by token cancellation. Reason: ");
throw;
}
catch (Exception ex)
{
Logger.Error(ex);
throw;
}
finally
{
Dispose();
}
}
I assume that the error is called from a method await HandleMessageAsync(updateModel);
where I used _cancellationTokenSource.Token.
I received next error on my server (Ubuntu 2G RAM, 2 Core, 40G SSD):
RevaluatePortfoliosService|The service was stopped by token cancellation. Reason: System.OperationCanceledException: The operation was canceled
But nothing could cause the cancellation. I don't understand why this is happening

Azure Function RabbitMq trigger stops receiving messages

I have Azure Function with RabbitMq trigger and it stops receiving any messages after certain time. The function is deployed in Azure. When I stop and then start again the function, it starts pulling messages again, but after a while it stops. When I run it locally on my machine the problem never occurs. My code looks like this:
[FunctionName(nameof(Bets))]
public async Task Bets([RabbitMQTrigger(nameof(Bets), ConnectionStringSetting = "RabbitConnection")] BasicDeliverEventArgs args,
[RabbitMQ(ConnectionStringSetting = "RabbitConnection")] IModel client, ILogger log)
{
var myQueueItem = Encoding.UTF8.GetString(args.Body);
var logEntry = new Log()
{
date = DateTime.UtcNow,
status = SuccessStatus,
input = myQueueItem,
queue = nameof(Bets)
};
try
{
var input = JsonConvert.DeserializeObject<Bet[]>(myQueueItem);
await _context.BulkInsertOrUpdateAsync(input);
log.LogInformation($"Finished input save: {myQueueItem}");
}
catch (Exception e)
{
client.BasicNack(args.DeliveryTag, false, true);
logEntry.status = "Error";
logEntry.error = e.Message;
log.LogError(e, e.Message, myQueueItem);
}
await _context.logs.AddAsync(logEntry);
await _context.SaveChangesAsync();
}

Windows 10 Universal App - Socket connection recurrent readings

I am following the Socket Example about StreamSockets. I can read from the server as a client. The example is https://social.msdn.microsoft.com/Forums/es-ES/79eda064-473d-4398-8fe3-72369e686c3c/comunicacion-tcpcip-con-streamsocket-y-datawriterdatareader?forum=esdevwindows
I'm building a Windows 10 Universal Application and I need continuous readings from a socket connection. I'm getting the first reading but then only empty strings.
Thanks!
Image capture response
Private StreamSocket socketForServer;
Private DataWriter cfaStreamWriter;
Private DataReader cfaStreamReader;
// Read socket data
Private Async void ReadData()
{
If (socketForServer == null) Then Return;
uint s = await cfaStreamReader.LoadAsync(1024);
String Data = cfaStreamReader.ReadString(s);
PrintData(Data);
var ignore = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () >=
ReadData());
}
// Connect to the bid controller through TCP Socket.
Public Async Task<bool> Connect()
{
socketForServer = New StreamSocket();
var hostname = New HostName(deviceSPACS_IP);
await socketForServer.ConnectAsync(hostname, deviceSPACS_PORT.ToString());
// send login
SendRawMessage("WELCOME TO SERVER");
cfaStreamReader = New DataReader(socketForServer.InputStream)
{
InputStreamOptions = InputStreamOptions.Partial
};
ReadData();
Return True;
}
// Disconnect from bid Controller
Public bool Disconnect()
{
If (socketForServer == null) Then Return False;
SendRawMessage("GOOD BYE AL SERVER");
cfaStreamReader.Dispose();
cfaStreamReader = null;
socketForServer.Dispose();
socketForServer = null;
Return True;
}
Private Async void SendRawMessage(String message)
{
cfaStreamWriter = New DataWriter(socketForServer.OutputStream); cfaStreamWriter.WriteString(message + "\r\n");
await cfaStreamWriter.StoreAsync();
await cfaStreamWriter.FlushAsync();
cfaStreamWriter.DetachStream();
cfaStreamWriter.Dispose();
cfaStreamWriter = null;
}

Read data from StreamSocketListener on RFComm bluetooth connected device C#

I'm developing an universal application Win8.1 / WP8.1
I'm able to discover and connect to the paired bluetooth devices (Stick readers - Rfid)
This is how I'm connecting
Variables
private IAsyncOperation<RfcommDeviceService> connectService;
private IAsyncAction connectAction;
private RfcommDeviceService rfcommService;
private RfcommServiceProvider rfcommProvider;
private StreamSocketListener listener;
private DataReader reader;
private DataWriter writer;
//Connection
public async Task ConnectToServiceAsync(string name)
{
DeviceInformation serviceInfo = null;
foreach (var device in devices)
{
if(device.Name == name)
{
serviceInfo = device;
break;
}
}
if (serviceInfo != null)
{
this.State = BluetoothConnectionState.Connecting;
try
{
// Initialize the target Bluetooth RFCOMM device service
connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
rfcommService = await connectService;
if (rfcommService != null)
{
rfcommProvider = await RfcommServiceProvider.CreateAsync(rfcommService.ServiceId);
// Create a socket and connect to the target
listener = new StreamSocketListener();
listener.ConnectionReceived += Listener_ConnectionReceived;
connectAction = listener.BindServiceNameAsync(rfcommService.ServiceId.AsString(), SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
await connectAction;//to make it cancellable
writer = new DataWriter(socket.OutputStream);
reader = new DataReader(socket.InputStream);
this.State = BluetoothConnectionState.Connected;
}
else
OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
}
catch (TaskCanceledException)
{
this.State = BluetoothConnectionState.Disconnected;
}
catch (Exception ex)
{
this.State = BluetoothConnectionState.Disconnected;
OnExceptionOccuredEvent(this, ex);
}
}
}
//Then wait for a connection over the listener
private async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
DataReader inputreader = new DataReader(args.Socket.InputStream);
while (true)
{
try
{
inputreader.InputStreamOptions = InputStreamOptions.Partial;
// Read first byte (length of the subsequent message, 255 or less).
uint sizeFieldCount = await inputreader.LoadAsync(1);
if (sizeFieldCount != 1)
{
// The underlying socket was closed before we were able to read the whole data.
return;
}
// Read the message.
uint messageLength = inputreader.ReadByte();
uint actualMessageLength = await inputreader.LoadAsync(messageLength);
if (messageLength != actualMessageLength)
{
// The underlying socket was closed before we were able to read the whole data.
return;
}
// Read the message and process it.
string message = inputreader.ReadString(actualMessageLength);
OnMessageReceivedEvent(this, message);
}
catch (Exception ex)
{
if (inputreader != null)
OnExceptionOccuredEvent(this, ex);
}
}
}
The problem is that the Bluetooth Stick Reader never send a connection request, it just read the rfid device ID and sends it over the serial port.
So, I'm able to connect to the device but I don't know how to actively listen or read the incoming data.
Any help will be appreciated.
RFCOMM communication is Client/Server model. You need to define a server to broadcast the service and a client connected to the service.
As I saw from the code you post, it only includes the server side code which provides the service but there was no client connecting to service. Only when the client connected to the service, the ConnectionReceived event will be fired.
I have written a sample which host the RFCOMM service in a console application and consume the service in Windows Runtime App before (Code Sample).
The client code is as following:
rfcommServiceInfoCollection = await DeviceInformation.FindAllAsync(
RfcommDeviceService.GetDeviceSelector(RfcommServiceId.ObexObjectPush));
var count = rfcommServiceInfoCollection.Count;
Debug.WriteLine("Count of RFCOMM Service: " + count);
if(count > 0)
{
lock (this)
{
streamSocket = new StreamSocket();
}
var defaultSvcInfo = rfcommServiceInfoCollection.FirstOrDefault();
rfcommDeviceService = await RfcommDeviceService.FromIdAsync(defaultSvcInfo.Id);
if(rfcommDeviceService == null)
{
Debug.WriteLine("Rfcomm Device Service is NULL, ID = {0}", defaultSvcInfo.Id);
return;
}
Debug.WriteLine("ConnectionHostName: {0}, ConnectionServiceName: {1}", rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
await streamSocket.ConnectAsync(rfcommDeviceService.ConnectionHostName, rfcommDeviceService.ConnectionServiceName);
By the way, do not forget to add the RFCOMM capabilities in your appxmanifest.
For example:
<m2:DeviceCapability Name="bluetooth.rfcomm">
<m2:Device Id="any">
<m2:Function Type="name:obexObjectPush" />
</m2:Device>
</m2:DeviceCapability
As Jeffrey said, this is a client/Server model, but in my case the client doesn't have any logic, and is not capable to request any connection.
Thank you for your samples, It helped a lot.
After trying several things I got some code working, and a "server" running and listening in the rfcomm service:
public async Task ConnectToServiceAsync(string name)
{
lock(this.interlock)
{
readBuffer = String.Empty;
}
DeviceInformation serviceInfo = null;
foreach (var device in devices)
{
if(device.Name == name)
{
serviceInfo = device;
break;
}
}
if (serviceInfo != null)
{
DeviceName = serviceInfo.Name;
this.State = BluetoothConnectionState.Connecting;
try
{
// Initialize the target Bluetooth RFCOMM device service
connectService = RfcommDeviceService.FromIdAsync(serviceInfo.Id);
rfcommService = await connectService;
if (rfcommService != null)
{
// Create a socket and connect to the target
socket = new StreamSocket();
connectAction = socket.ConnectAsync(rfcommService.ConnectionHostName, rfcommService.ConnectionServiceName, SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
await connectAction;//to make it cancellable
writer = new DataWriter(socket.OutputStream);
reader = new DataReader(socket.InputStream);
State = BluetoothConnectionState.Connected;
Task taskReceive = Task.Run(async () => { ListenForMessagesAsync(socket); });
taskReceive.ConfigureAwait(false);
}
else
OnExceptionOccuredEvent(this, new Exception("Unable to create service.\nMake sure that the 'bluetooth.rfcomm' capability is declared with a function of type 'name:serialPort' in Package.appxmanifest."));
}
catch (TaskCanceledException)
{
this.State = BluetoothConnectionState.Disconnected;
}
catch (Exception ex)
{
this.State = BluetoothConnectionState.Disconnected;
OnExceptionOccuredEvent(this, ex);
}
}
}
And the listener in
private async Task ListenForMessagesAsync(StreamSocket localsocket)
{
while (socket != null)
{
try
{
string message = String.Empty;
DataReader dataReader = new DataReader(localsocket.InputStream);
dataReader.InputStreamOptions = InputStreamOptions.Partial;
// Read the message and process it.
lock (this.interlock)
{
if (!message.Contains("\r\n"))
readBuffer = readBuffer + message;
else
{
var data = message.Split('\r');
readBuffer = readBuffer + data[0];
}
if (readBuffer.Length == 15)
{
readBuffer = readBuffer.Replace("\r\n", "");
OnMessageReceivedEvent(this, readBuffer);
readBuffer = String.Empty;
}
if (readBuffer.Length > 15 || (readBuffer.Length < 15 && readBuffer.Contains("\r\n")))
readBuffer = String.Empty;
}
}
catch (Exception ex)
{
if (socket != null)
OnExceptionOccuredEvent(this, ex);
}
}
}

Windows service Signalr authentication expires

I have a Windows Services which connects to a Signalr Hub.
The Service receives barcode scans and sends the barcode to the Hub.
Users request en webpage which uses jTable to show the scanned barcodes in a grid.
The webapplication uses winforms authentication with sliding expiration.
This works fine till some point in time the authentication cookie becomes invalid. How can i detect if an authentication cookie becomes invalid?
At startup off the service I create a hub connection.
private static IHubProxy _bufferProxy;
private static HubConnection _hubConnection;
protected static async void InitBufferHub()
{
bool connected = false;
while(!connected)
{
try
{
_hubConnection = new HubConnection(Settings.Default.HubConnection);
Cookie returnedCookie;
var authResult = AuthenticateUser("user", "password", out returnedCookie);
if (authResult)
{
_hubConnection.CookieContainer = new CookieContainer();
_hubConnection.CookieContainer.Add(returnedCookie);
Log.Debug("User logged in");
}
else
{
Log.Debug("Login failed");
}
_bufferProxy = _hubConnection.CreateHubProxy("buffer");
await _hubConnection.Start();
connected = true;
Log.Debug("Hub proxy created");
}
catch (Exception ex)
{
Log.Error("OnStart", ex);
Thread.Sleep(100);
}
}
}
internal static async void SendBufferItem(BufferItem bufferItem)
{
try
{
if (_hubConnection.State == ConnectionState.Disconnected)
{
_bufferProxy = null;
_hubConnection.Dispose();
InitBufferHub();
}
await _bufferProxy.Invoke("RecordCreated", bufferItem);
}
catch (Exception ex)
{
Log.Error("SendBufferItem error: ", ex);
}
}

Categories