Message properties on Mqtt protocol - azure-iot-hub

I'm having problems receiving message properties and message system properties on the Mqtt protocol. But it works fine when using TransportType.Amqp.
Is the explanation to be found in section "Receiving messages" at this page?
https://azure.microsoft.com/da-dk/documentation/articles/iot-hub-mqtt-support/
If yes, what does it mean and how do I do that?
Receiver code:
I'm using 1.0.12 of Microsoft.Azure.Devices.Client from nuget and all the dependencies.
//connectString: HostName=<host name>;DeviceId=<device id>;SharedAccessKey=<key>
//var deviceClient = DeviceClient.CreateFromConnectionString(connectString,TransportType.Amqp);
var deviceClient = DeviceClient.CreateFromConnectionString(connectString, TransportType.Mqtt);
while (true)
{
var message = await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(2));
if (message != null)
{
//message.MessageId is null on Mqtt but not for Amqp!
}
}
Sender code:
I’m using version 1.0.11 of Microsoft.Azure.Devices.dll
string messageId = Guid.NewGuid().ToString("D");
var iotHubConnection = "HostName=<host>;SharedAccessKeyName=<...>;SharedAccessKey=<...>";
var serviceClient = ServiceClient.CreateFromConnectionString(iotHubConnection);
if (serviceClient == null) throw new Exception("ServiceClient create failed");
var serviceMessage = new Microsoft.Azure.Devices.Message(Encoding.UTF8.GetBytes("Hello World"));
serviceMessage.Ack = DeliveryAcknowledgement.Full;
serviceMessage.MessageId = messageId;
serviceMessage.Properties["message-id"] = messageId;
serviceClient.SendAsync("0123", serviceMessage).Wait();
The C sample code reads properties, but but the csharp sample code does not:
https://github.com/Azure/azure-iot-sdks/blob/master/c/iothub_client/samples/iothub_client_sample_mqtt/iothub_client_sample_mqtt.c

Related

SEC_ERROR_REVOKED_CERTIFICATE error while accesing the url in browser

Hi i am getting below error while trying to access the website which is hosted in IIS 8 for which the SSL certificate had got expired and i installed the new SSL certificate provided by GoDaddy, it was all working fine for 2 days and now it shows the below error. Let me know if anyone can figure out what is the issue
using Microsoft.CognitiveServices.Speech;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace SPT
{
class Program
{
public static async Task RecognizeSpeechAsync()
{
// Creates an instance of a speech config with specified subscription key and service region.
// Replace with your own subscription key // and service region (e.g., "westus").
var config = SpeechConfig.FromSubscription(" 7cf359266c964dc789960abe063cc65b", "westus");
// Creates a speech recognizer.
using (var recognizer = new SpeechRecognizer(config))
{
Console.WriteLine("Say something...");
// Starts speech recognition, and returns after a single utterance is recognized. The end of a
// single utterance is determined by listening for silence at the end or until a maximum of 15
// seconds of audio is processed. The task returns the recognition text as result.
// Note: Since RecognizeOnceAsync() returns only a single utterance, it is suitable only for single
// shot recognition like command or query.
// For long-running multi-utterance recognition, use StartContinuousRecognitionAsync() instead.
var result = await recognizer.RecognizeOnceAsync();
// Checks result.
if (result.Reason == ResultReason.RecognizedSpeech)
{
Console.WriteLine($"We recognized: {result.Text}");
}
else if (result.Reason == ResultReason.NoMatch)
{
Console.WriteLine($"NOMATCH: Speech could not be recognized.");
}
else if (result.Reason == ResultReason.Canceled)
{
var cancellation = CancellationDetails.FromResult(result);
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
Console.WriteLine($"CANCELED: Did you update the subscription info?");
}
}
}
}
public static async Task SynthesisToSpeakerAsync()
{
// Creates an instance of a speech config with specified subscription key and service region.
// Replace with your own subscription key and service region (e.g., "westus").
// The default language is "en-us".
var config = SpeechConfig.FromSubscription("7cf359266c964dc789960abe063cc65b", "westus");
// Creates a speech synthesizer using speaker as audio output.
using (var synthesizer = new SpeechSynthesizer(config))
{
// Receive a text from console input and synthesize it to speaker.
Console.WriteLine("Type some text that you want to speak...");
Console.Write("> ");
string text = Console.ReadLine();
using (var result = await synthesizer.SpeakTextAsync(text))
{
if (result.Reason == ResultReason.SynthesizingAudioCompleted)
{
Console.WriteLine($"Speech synthesized to speaker for text [{text}]");
}
else if (result.Reason == ResultReason.Canceled)
{
var cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
if (cancellation.Reason == CancellationReason.Error)
{
Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");
Console.WriteLine($"CANCELED: Did you update the subscription info?");
}
}
}
// This is to give some time for the speaker to finish playing back the audio
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
public static async Task SynthesisToVideoAsync()
{
var apiUrl = "https://api.videoindexer.ai";
var accountId = "56fbb8f8-b9a8-4119-b46a-fa5fb6668ddd";
var location = "westus2";
var apiKey = "6f354f730bc141f9bc3e57e73c6001b0";
System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol | System.Net.SecurityProtocolType.Tls12;
// create the http client
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = false;
var client = new HttpClient(handler);
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
// obtain account access token
var accountAccessTokenRequestResult = client.GetAsync($"{apiUrl}/auth/{location}/Accounts/{accountId}/AccessToken?allowEdit=true").Result;
var accountAccessToken = accountAccessTokenRequestResult.Content.ReadAsStringAsync().Result.Replace("\"", "");
client.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key");
// upload a video
var content = new MultipartFormDataContent();
Debug.WriteLine("Uploading...");
// get the video from URL
var videoUrl = "VIDEO_URL"; // replace with the video URL
// as an alternative to specifying video URL, you can upload a file.
// remove the videoUrl parameter from the query string below and add the following lines:
//FileStream video =File.OpenRead(Globals.VIDEOFILE_PATH);
//byte[] buffer =newbyte[video.Length];
//video.Read(buffer, 0, buffer.Length);
//content.Add(newByteArrayContent(buffer));
var uploadRequestResult = client.PostAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos?accessToken={accountAccessToken}&name=some_name&description=some_description&privacy=private&partition=some_partition&videoUrl={videoUrl}", content).Result;
var uploadResult = uploadRequestResult.Content.ReadAsStringAsync().Result;
// get the video id from the upload result
var videoId = JsonConvert.DeserializeObject<dynamic>(uploadResult)["id"];
Debug.WriteLine("Uploaded");
Debug.WriteLine("Video ID: " + videoId);
// obtain video access token
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
var videoTokenRequestResult = client.GetAsync($"{apiUrl}/auth/{location}/Accounts/{accountId}/Videos/{videoId}/AccessToken?allowEdit=true").Result;
var videoAccessToken = videoTokenRequestResult.Content.ReadAsStringAsync().Result.Replace("\"", "");
client.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key");
// wait for the video index to finish
while (true)
{
Thread.Sleep(10000);
var videoGetIndexRequestResult = client.GetAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos/{videoId}/Index?accessToken={videoAccessToken}&language=English").Result;
var videoGetIndexResult = videoGetIndexRequestResult.Content.ReadAsStringAsync().Result;
var processingState = JsonConvert.DeserializeObject<dynamic>(videoGetIndexResult)["state"];
Debug.WriteLine("");
Debug.WriteLine("State:");
Debug.WriteLine(processingState);
// job is finished
if (processingState != "Uploaded" && processingState != "Processing")
{
Debug.WriteLine("");
Debug.WriteLine("Full JSON:");
Debug.WriteLine(videoGetIndexResult);
break;
}
}
// search for the video
var searchRequestResult = client.GetAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos/Search?accessToken={accountAccessToken}&id={videoId}").Result;
var searchResult = searchRequestResult.Content.ReadAsStringAsync().Result;
Debug.WriteLine("");
Debug.WriteLine("Search:");
Debug.WriteLine(searchResult);
// get insights widget url
var insightsWidgetRequestResult = client.GetAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos/{videoId}/InsightsWidget?accessToken={videoAccessToken}&widgetType=Keywords&allowEdit=true").Result;
var insightsWidgetLink = insightsWidgetRequestResult.Headers.Location;
Debug.WriteLine("Insights Widget url:");
Debug.WriteLine(insightsWidgetLink);
// get player widget url
var playerWidgetRequestResult = client.GetAsync($"{apiUrl}/{location}/Accounts/{accountId}/Videos/{videoId}/PlayerWidget?accessToken={videoAccessToken}").Result;
var playerWidgetLink = playerWidgetRequestResult.Headers.Location;
Debug.WriteLine("");
Debug.WriteLine("Player Widget url:");
Debug.WriteLine(playerWidgetLink);
}
static void Main()
{
RecognizeSpeechAsync().Wait();
SynthesisToSpeakerAsync().Wait();
SynthesisToVideoAsync().Wait();
Console.WriteLine("Please press a key to continue.");
Console.ReadLine();
}
}
}

How to create a durable publisher/subscriber topic using the AMQP.Net Lite library in .NET Core with clientId and subscriber name and topic name

I am new to ActiveMQ, but I tried and am able to create a durable publisher, but I am not able to set Client Id, because I am not finding any properties with client Id and am even unable to find in Google. It will be great help if I will get some sample code.
Note:
Not with the NMS protocol. I am using AMQP.Net Lite with ActiveMQ in the .NET Core Web API for creating a durable publisher/subscriber with ClientId.
In order to create a durable subscription to ActiveMQ or ActiveMQ Artemis your client needs to do a couple things.
Set a unique "client-id" for the client using the AMQP 'ContainerId' property which can be seen in the code below. The client must use that same container ID every time it connects and recovers it's durable subscription.
Create a new Session.
Create a new Receiver for the address (in this case Topic) that you want to subscribe to. The Source of a durable subscription need to have the address set to a Topic address (in ActiveMQ this is topic://name). The Source also needs the expiray policy set to NEVER, the Source must also have the terminus durability state set to UNSETTLED_STATE, and the distribution mode set to COPY.
Once the Receiver is created then you can either set an onMessage handler in start or call receive to consume messages (assuming you've granted credit for the broker to send you any).
using System;
using Amqp;
using Amqp.Framing;
using Amqp.Types;
using Amqp.Sasl;
using System.Threading;
namespace aorg.apache.activemq.examples
{
class Program
{
private static string DEFAULT_BROKER_URI = "amqp://localhost:5672";
private static string DEFAULT_CONTAINER_ID = "client-1";
private static string DEFAULT_SUBSCRIPTION_NAME = "test-subscription";
private static string DEFAULT_TOPIC_NAME = "test-topic";
static void Main(string[] args)
{
Console.WriteLine("Starting AMQP durable consumer example.");
Console.WriteLine("Creating a Durable Subscription");
CreateDurableSubscription();
Console.WriteLine("Attempting to recover a Durable Subscription");
RecoverDurableSubscription();
Console.WriteLine("Unsubscribe a durable subscription");
UnsubscribeDurableSubscription();
Console.WriteLine("Attempting to recover a non-existent durable subscription");
try
{
RecoverDurableSubscription();
throw new Exception("Subscription was not deleted.");
}
catch (AmqpException)
{
Console.WriteLine("Recover failed as expected");
}
Console.WriteLine("Example Complete.");
}
// Creating a durable subscription involves creating a Receiver with a Source that
// has the address set to the Topic name where the client wants to subscribe along
// with an expiry policy of 'never', Terminus Durability set to 'unsettled' and the
// Distribution Mode set to 'Copy'. The link name of the Receiver represents the
// desired name of the Subscription and of course the Connection must carry a container
// ID uniqure to the client that is creating the subscription.
private static void CreateDurableSubscription()
{
Connection connection = new Connection(new Address(DEFAULT_BROKER_URI),
SaslProfile.Anonymous,
new Open() { ContainerId = DEFAULT_CONTAINER_ID }, null);
try
{
Session session = new Session(connection);
Source source = CreateBasicSource();
// Create a Durable Consumer Source.
source.Address = DEFAULT_TOPIC_NAME;
source.ExpiryPolicy = new Symbol("never");
source.Durable = 2;
source.DistributionMode = new Symbol("copy");
ReceiverLink receiver = new ReceiverLink(session, DEFAULT_SUBSCRIPTION_NAME, source, null);
session.Close();
}
finally
{
connection.Close();
}
}
// Recovering an existing subscription allows the client to ask the remote
// peer if a subscription with the given name for the current 'Container ID'
// exists. The process involves the client attaching a receiver with a null
// Source on a link with the desired subscription name as the link name and
// the broker will then return a Source instance if this current container
// has a subscription registered with that subscription (link) name.
private static void RecoverDurableSubscription()
{
Connection connection = new Connection(new Address(DEFAULT_BROKER_URI),
SaslProfile.Anonymous,
new Open() { ContainerId = DEFAULT_CONTAINER_ID }, null);
try
{
Session session = new Session(connection);
Source recoveredSource = null;
ManualResetEvent attached = new ManualResetEvent(false);
OnAttached onAttached = (link, attach) =>
{
recoveredSource = (Source) attach.Source;
attached.Set();
};
ReceiverLink receiver = new ReceiverLink(session, DEFAULT_SUBSCRIPTION_NAME, (Source) null, onAttached);
attached.WaitOne(10000);
if (recoveredSource == null)
{
// The remote had no subscription matching what we asked for.
throw new AmqpException(new Error());
}
else
{
Console.WriteLine(" Receovered subscription for address: " + recoveredSource.Address);
Console.WriteLine(" Recovered Source Expiry Policy = " + recoveredSource.ExpiryPolicy);
Console.WriteLine(" Recovered Source Durability = " + recoveredSource.Durable);
Console.WriteLine(" Recovered Source Distribution Mode = " + recoveredSource.DistributionMode);
}
session.Close();
}
finally
{
connection.Close();
}
}
// Unsubscribing a durable subscription involves recovering an existing
// subscription and then closing the receiver link explicitly or in AMQP
// terms the close value of the Detach frame should be 'true'
private static void UnsubscribeDurableSubscription()
{
Connection connection = new Connection(new Address(DEFAULT_BROKER_URI),
SaslProfile.Anonymous,
new Open() { ContainerId = DEFAULT_CONTAINER_ID }, null);
try
{
Session session = new Session(connection);
Source recoveredSource = null;
ManualResetEvent attached = new ManualResetEvent(false);
OnAttached onAttached = (link, attach) =>
{
recoveredSource = (Source) attach.Source;
attached.Set();
};
ReceiverLink receiver = new ReceiverLink(session, DEFAULT_SUBSCRIPTION_NAME, (Source) null, onAttached);
attached.WaitOne(10000);
if (recoveredSource == null)
{
// The remote had no subscription matching what we asked for.
throw new AmqpException(new Error());
}
else
{
Console.WriteLine(" Receovered subscription for address: " + recoveredSource.Address);
Console.WriteLine(" Recovered Source Expiry Policy = " + recoveredSource.ExpiryPolicy);
Console.WriteLine(" Recovered Source Durability = " + recoveredSource.Durable);
Console.WriteLine(" Recovered Source Distribution Mode = " + recoveredSource.DistributionMode);
}
// Closing the Receiver vs. detaching it will unsubscribe
receiver.Close();
session.Close();
}
finally
{
connection.Close();
}
}
// Creates a basic Source type that contains common attributes needed
// to describe to the remote peer the features and expectations of the
// Source of the Receiver link.
private static Source CreateBasicSource()
{
Source source = new Source();
// These are the outcomes this link will accept.
Symbol[] outcomes = new Symbol[] {new Symbol("amqp:accepted:list"),
new Symbol("amqp:rejected:list"),
new Symbol("amqp:released:list"),
new Symbol("amqp:modified:list") };
// Default Outcome for deliveries not settled on this link
Modified defaultOutcome = new Modified();
defaultOutcome.DeliveryFailed = true;
defaultOutcome.UndeliverableHere = false;
// Configure Source.
source.DefaultOutcome = defaultOutcome;
source.Outcomes = outcomes;
return source;
}
}
}

How to get profile picture(Image) from People App

I'm tring to get the profile picture from People App. I used
Windows.ApplicationModel.Contacts.Contact contact = new Contact();
I got Thumbnail from propety contact.Thumbnail.
I need to convert this Thumbnail to StorageFile. Could you please give inputs to solve this issue?
And, while using the following code:
IRandomAccessStreamWithContentType stream = awaitcontactInfo.Thumbnail.OpenReadAsync();
if(stream != null && stream.Size > 0)
{
//
}
Sometimes I'm getting RPC Server is unavailable Exception. Sometimes the streamSize is Zero.
You are creating new instance of Contact class. You don't have to do that to pick contact from people. You should use ContactPicker.
var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
contactPicker.CommitButtonText = "Select";
ContactInformation contact = await contactPicker.PickSingleContactAsync();
if (contact != null)
{
IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();
if (stream != null && stream.Size > 0)
{
var file = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("MyContactThumb.png", CreationCollisionOption.GenerateUniqueName);
// You can also use FileSavePicker to save file in user defined location.
Windows.Storage.Streams.Buffer MyBuffer = new Windows.Storage.Streams.Buffer(Convert.ToUInt32(stream.Size));
IBuffer iBuf = await stream.ReadAsync(MyBuffer, MyBuffer.Capacity, InputStreamOptions.None);
await FileIO.WriteBufferAsync(file, iBuf);
}
}

Calling Webmethod containing byte array (as in paramaeter)parameter with ksoap2 on android

There is WEB service written on C# with next method:
[WebMethod]
public string ByteArrTest(byte[] Buffer)
{
if (Buffer == null) return "buffer is null";
else return Buffer.Length.ToString() + " is buffer length";
}
i 'ld like call this method from android device using Ksoap2 library alike belove (simplified):
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
new MarshalBase64().register(envelope);
envelope.encodingStyle = SoapEnvelope.ENC;
SoapObject request = new SoapObject(this.getNameSpace(), this.getMethodName());
PropertyInfo pi4 = new PropertyInfo();
pi4.setName("Buffer");
byte [] b="this text".getBytes();
pi4.setValue(b);
pi4.setType(byte[].class);
// request.addProperty("buffer", "bytes".getBytes);
request.addProperty(pi4);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport =
new HttpTransportSE(this.getURL());//
androidHttpTransport.call(this.getSoapAction(), envelope);
Object response = envelope.getResponse();
//next implementation
Responce always is "buffer is null"
what is incorrect or wrong?
Thanks for any attention
Posting the whole of your method in Android calling the web service would help more.
I'm using KSoap in an Android project I'm currently working on and I'm retrieving strings. Heres one of my methods modified to match what you need:
private static String NAMESPACE = "http://tempuri.org/";
private static String SOAP_ACTION = "http://tempuri.org/";
private static final String URL = "Your url link to your web services asmx file";
public static String ByteArrTestCall(byte[] t) {
String resTxt = null;
SoapObject request = new SoapObject(NAMESPACE, "ByteArrTest");
// Add the property to request object
request.addProperty("Buffer", t);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport.debug = true;
try
{
androidHttpTransport.call(SOAP_ACTION+"ByteArrTest", envelope);
SoapPrimitive receivedString = (SoapPrimitive) envelope.getResponse();
resTxt = receivedString.toString();
}
catch(Exception e)
{
resTxt = androidHttpTransport.requestDump;
return e.toString() + resTxt;
}
return resTxt;
}

WCF message body showing <s:Body>... stream ...</s:Body> after modification

Trying to use MessageInspector to modify the message before the wcf service through the proxy. However while debugging the message body does not gets copied and body shows
<s:Body>... stream ...</s:Body>
What is the problem with the code?
public class CustomWCFMessageInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
request = ModifyMessage(request);
return null;
}
private Message ModifyMessage(Message oldMessage)
{
Message newMessage = null;
MessageBuffer msgbuf = oldMessage.CreateBufferedCopy(int.MaxValue);
Message tmpMessage = msgbuf.CreateMessage();
XmlDictionaryReader xdr = tmpMessage.GetReaderAtBodyContents();
XDocument xd = ConvertToXDocument(xdr);
EmitTags(xd);
var ms = new MemoryStream();
var xw = XmlWriter.Create(ms);
xd.Save(xw);
xw.Flush();
xw.Close();
ms.Position = 0;
XmlReader xr = XmlReader.Create(ms);
newMessage = Message.CreateMessage(tmpMessage.Version, null, xr);
newMessage.Headers.CopyHeadersFrom(tmpMessage);
newMessage.Properties.CopyProperties(tmpMessage.Properties);
return newMessage;
}
}
Here is solution:
if you call Message.ToString() you will get
..stream..
Instead use System.Xml.XmlWriter. Here is a sample:
MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
Message msg = buffer.CreateMessage();
StringBuilder sb = new StringBuilder();
using (System.Xml.XmlWriter xw = System.Xml.XmlWriter.Create(sb))
{
msg.WriteMessage(xw);
xw.Close();
}
Console.WriteLine("Message Received:\n{0}", sb.ToString());
The problem was that the newMessage body was not shown in the watch window after doing ToString()
Created the buffered copy of the message to be shown in the debugger.
MessageBuffer messageBuffer = newMessage.CreateBufferedCopy(int.MaxValue);
Message message = messageBuffer.CreateMessage();
So there is No problem in the code. It is just that the debugger is not showing the message body as mentioned in the link below
http://msdn.microsoft.com/en-us/library/ms734675(v=VS.90).aspx
in the Accessing the Message Body for Debugging section.
I suspect ToString will return what you are getting. ToString is often used for debugging, and hence only shows you basic information about the object. You need to do something like this in ConvertToXDocument:
XDocument x = XDocument.Load(xdr);