I'm trying to use "MQTTnet" in a Xamarin application. It connects fine but when I try to publish anything, well, it publishs but after about 5 seconds it throw the following exception
MQTTnet.Exceptions.MqttCommunicationTimedOutException
I'm not quite sure about what's happening there, the message is received successfully by the server
Server auth xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 from 192.168.1.8
Client xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 connected
Total connections: 3
$SYS/POezxDu/new/clients xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612
hello/world hey
Client xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612 disconnected
Total connections: 2
$SYS/POezxDu/disconnect/clients xmr/47cd7021-0f32-4cd4-b549-e8ebce2df612
Below is the code:
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using System.Threading;
namespace MQTTXamarin
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Login : ContentPage
{
public Login()
{
InitializeComponent();
}
private void Btn_Login_Clicked(object sender, EventArgs e)
{
MqttConnect();
}
/* MQTT */
readonly IMqttClient client = new MqttFactory().CreateMqttClient();
private async void MqttConnect()
{
var options = new MqttClientOptionsBuilder()
.WithClientId("xmr/" + Guid.NewGuid().ToString())
.WithTcpServer("192.168.1.200", 1883)
.WithCredentials("DyPFunIOcljUT51i", "K1YMeKkvrK6yMvm7IlHadBA6JDBKzPGc")
.Build();
await client.ConnectAsync(options, CancellationToken.None);
var message = new MqttApplicationMessageBuilder()
.WithTopic("hello/world")
.WithPayload("hey")
.WithExactlyOnceQoS()
.Build();
await client.PublishAsync(message, CancellationToken.None);
}
}
}
Am I doing something wrong or is this buggy?
This issue was solved changing the
.WithExactlyOnceQoS()
to
.WithAtLeastOnceQoS()
Related
I'm having an issue when using SignalR and IIS on my Windows 10 machine. The problem is that IIS only allows for 10 concurrent connections. When The 10th connection is reached, the client side HubConnection will stay in the Connecting state for a long time.
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static int usedConnections = 0;
static void Main(string[] args)
{
Foo();
while (true) { }
}
static async void Foo()
{
for(int i = 0; i < 15; i++)
{
await SetupSignalR();
}
}
static async Task SetupSignalR()
{
//Set connection
var hub = new HubConnection("http://MyComputer/MyIISApp");
hub.TraceLevel = TraceLevels.All;
hub.TraceWriter = Console.Out;
//Make proxy to hub based on hub name on server
var myHub = hub.CreateHubProxy("MyIISHub");
//Start connection
hub.TransportConnectTimeout = TimeSpan.FromSeconds(5);
await hub.Start();
usedConnections++;
Console.WriteLine($"Used Conenctions: {usedConnections}");
return;
}
}
}
After a reasonable period of time I would like to display a message to the user that the HubConnection is unable to connect to the server, but I cant figure out how to either set a timeout or trigger an event. What can I do to notify the user that IIS isn't accepting the connection request?
According to your description, I suggest you could try to write the codes to monitor the connection time, if the time has exceed the 30 seconds, you could directly stop connect to the signlar server and show a error message.
Besides, the connection limit for the IIS is only happened on the windows10. If you used the windows server, there is no limit for the IIS connection.
I am currently working with the rabbitMQ server, As when i try working in c# console application, the publish exchange working and successfully save in the server and the message will lively appear in the console but when i apply my source code in the C# windows form, it will not get all the message sent by the publisher. I put the method in the constructor event but no happen at all it will not receive any message.
Please see source code below
using Publisher;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
using RabbitMQ.Client.Events;
using System.Diagnostics;
namespace Consumer
{
public partial class Consumer : Form
{
private EventingBasicConsumer consumer;
ConnectionFactory factory;
public Consumer()
{
factory = new ConnectionFactory() { HostName = Definition.HOSTNAME };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: Definition.EXCHANGE, type: ExchangeType.Fanout);
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
exchange: Definition.EXCHANGE,
routingKey: "");
Debug.WriteLine(" [*] Waiting for Exchange ARexchange.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (sender, ea) =>
{
var body = ea.Body;
var message = Encoding.UTF8.GetString(body);
Debug.WriteLine(" [x] {0}", message);
};
channel.BasicConsume(
queueName,
autoAck: false,
consumer: consumer);
}
InitializeComponent();
}
private void Consumer_Load(object sender, EventArgs e)
{
}
private void setExchange()
{
lblExchange.Text = Definition.EXCHANGE;
}
}
}
Please read this: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
When those using statements exit, the channel and connection will be closed. Change your code to save those as instance variables in the Consumer class. Then, when your form exits, you can clean up those two instances.
If you provide your code in a repository that can be cloned, compiled and run people could assist you by submitting pull requests to improve your code.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
I have a WS server and I would like to broadcast messages from that server (using another web app) to all HoloLens devices that are connected to the session.
First I have implemented a MessageWebSocket client in the Hololens app that initiated a connection with a sample public WS server echo.websocket.org just to check if the setup is right on the client side. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if WINDOWS_UWP
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Web;
using System;
#endif
public class WebSocketClient : MonoBehaviour
{
void Start()
{
#if WINDOWS_UWP
int msgTime = 5;
int fadeTime = 1;
guiPhraseReporter.QueueRaport("START", msgTime, fadeTime);
MessageWebSocket ws = new MessageWebSocket();
ws.Control.MessageType = SocketMessageType.Utf8;
ws.MessageReceived += (MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) =>
{
guiPhraseReporter.QueueRaport("Trying to receive message...", msgTime, fadeTime);
try
{
using (DataReader dataReader = args.GetDataReader())
{
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
string message = dataReader.ReadString(dataReader.UnconsumedBufferLength);
Debug.Log(message);
}
}
catch (Exception ex)
{
Debug.Log("Error occurred");
}
};
ws.Closed += (IWebSocket sender, WebSocketClosedEventArgs args) => {
Debug.Log("WS closed");
};
try
{
Task connectTask = ws.ConnectAsync(new Uri("ws://echo.websocket.org")).AsTask();
connectTask.ContinueWith(async _ =>
{
string message = "Hello, World!";
using (DataWriter dataWriter = new DataWriter(ws.OutputStream))
{
dataWriter.WriteString(message);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
Debug.Log("Sending Hello World");
});
}
catch (Exception ex)
{
WebErrorStatus webErrorStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
// Add additional code here to handle exceptions.
Debug.Log(ex);
}
#endif
}
}
And it works fine, I'm able to send a message to the server, and it is echoed back and received correctly by the client.
Things however mess up when I use the actual server I'll be testing on. On my server, I have replicated the behavior from the echo.websocket.org and I echo back any message sent. I'm able to connect, the connection is not closed (Closed is never called), but I don't receive any messages.
If I test both servers using the web browser (with chrome's Smart Websocket Extension), they both work. The only difference (and only possible lead I got) is that the sample server (the one that works on Hololens) sends more headers upon connection:
vs my server:
Maybe there is some easier way to do this, but so far I didn't find any good WS wrappers that would work on UWP. Any help appreciated.
It was faulty logic on my server app after all. So there was no problem with WS communication to begin with, thank you for your time.
I have a basic Hello World console program connecting to a web server but none of my callbacks are invoked (nothing gets printed to the console).
using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("start ...");
try
{
// http://docs.servicestack.net/csharp-server-events-client
// ServiceSack.Client
var client = new ServerEventsClient("http://localhost:9999/bus/api/v1/subscribe/karli/head/0")
{
OnConnect = connectEvent => Console.WriteLine($"OnMessage {connectEvent}"),
OnCommand = cmd => Console.WriteLine($"OnCommand {cmd}"),
OnMessage = msg => Console.WriteLine($"OnMessage {msg}"),
OnUpdate = upd => Console.WriteLine($"OnUpdate {upd}"),
OnException = err => Console.WriteLine($"OnException {err}")
}.Start();
// keep main thread running ...
var a = Console.Read();
}
catch (Exception ex)
{
Console.WriteLine("dasda {0}", ex);
}
}
private static void OnMessage(ServerEventMessage message)
{
Console.WriteLine($"OnMessage {message}");
}
}
}
while the curl works as expected
$ curl "http://localhost:9999/bus/api/v1/subscribe/karli/head/0/event-stream"
{"key":"1","offset":0,"value":{}}
{"key":"1","offset":1,"value":{}}
{"key":"1","offset":2,"value":{}}
{"key":"1","offset":3,"value":{}}
{"key":"1","offset":4,"value":{}}
{"key":"1","offset":5,"value":{}}
{"key":"1","offset":6,"value":{}}
What am I missing here?
The ServerEventsClient needs to be initialized with the BaseUrl where your ServiceStack Service is located. If you're not hosting ServiceStack at a custom path it would just be host name, e.g:
var client = new ServerEventsClient("http://localhost:9999/") {
///...
}.Start();
As a complete beginner in the field of instant messaging (using XMPP protocol), as well as windows phone 8.1 app development; I am trying to start off by using xmedianet library in order to connect to a server and communicate using XMPP protocol. After implementing the following example and tweaking it to my needs.
Here's the part of the code where I configure the connection parameters:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using WP8Xmpp.Resources;
using System.Net.XMPP;
using System.Net.Sockets;
using System.Threading;
namespace WP8Xmpp
{
public partial class MainPage : PhoneApplicationPage
{
private Boolean IsXmppSuccess { get; set; }
/// <summary>
/// Xmpp Client
/// </summary>
public XMPPClient ObjXmppClient { get; set; }
/// <summary>
/// XMPP Connection
/// </summary>
public XMPPConnection ObjXmppCon { get; set; }
// Constructor
public MainPage()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
IsXmppValid();
}
private void IsXmppValid()
{
ObjXmppClient = new XMPPClient();
//initializing the xmpp client with credentials
ObjXmppClient.JID = "user#domain.com";
ObjXmppClient.JID.Resource = Guid.NewGuid().ToString();
ObjXmppClient.Password = "acc_password";
ObjXmppClient.Server = "server_uri";*/
ObjXmppClient.AutoReconnect = true;
ObjXmppClient.Port = 81; // I've already tried 5222 but 81 is the correct port in this server's case.
ObjXmppClient.RetrieveRoster = true;
ObjXmppClient.PresenceStatus = new PresenceStatus() { PresenceType = PresenceType.available, IsOnline = true };
ObjXmppClient.AutoAcceptPresenceSubscribe = true;
ObjXmppClient.AttemptReconnectOnBadPing = true;
ObjXmppCon = new XMPPConnection(ObjXmppClient);
ObjXmppCon.Connect();
ObjXmppClient.Connect();
//initializing the xmpp connection
ObjXmppCon.OnAsyncConnectFinished += ObjXmppCon_OnAsyncConnectFinished;
ObjXmppClient.OnStateChanged += new EventHandler(xMPPClient_OnStateChanged);
Thread.Sleep(2000);
} ...
When I launch this application using the WP 8.1 emulator and attempt a connection. Everything works fine until the Resource Binding step. I get the following output on the VS2013 console:
<--stream:features><ver xmlns="urn:xmpp:features:rosterver"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>
Setting state to CanBind
Setting state to Binding
<--<
<--iq id="xxxxxxxx-xxxx-xxxx-xxxx-0f08b82b9f1f" to="user#domain/Resource" xmlns="jabber:client" type="result"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>user#domain/Resource</jid></bind></iq>
Followed by nothingness except for a few "thread exit" messages and the program terminating after a few minutes.
I've been at it for days now.. I've tried all possible scenarios for the connection parameters, even tried fiddling with the library's code to no avail. Could anyone try to replicate this configuration with the same library to see if it's a problem on my side?
Note: connection to the server with the same account using another xmpp client works just fine.
Turned out the problem was that, for some reason, the "Bound" state was not firing even though the binding attempt returned a successful result. I've managed to "fix" this the ugly way by using Thread.sleep() and then changing the state manually to "bound" (note that the same trick is used to get to the "session" state). Here's a sample of my "patchwork" code:
void xMPPClient_OnStateChanged(object sender, EventArgs e)
{
switch (ObjXmppClient.XMPPState)
{
case XMPPState.Binding:
this.Dispatcher.BeginInvoke(() =>
{
Thread.Sleep(2000);
ObjXmppClient.XMPPState = System.Net.XMPP.XMPPState.Bound;
}
);
break;
case XMPPState.Sessioning:
this.Dispatcher.BeginInvoke(() =>
{
Thread.Sleep(2000);
ObjXmppClient.XMPPState = System.Net.XMPP.XMPPState.Session;
}
);
break; ...