I want to create Publisher and Subscriber Model using MSMQ Multicast feature.
I have already followed the answer in the link without success MSMQ - Cannot receive from Multicast queues
Messages getting sent and received in local machine.
Sender:
using (var helloQueue = new MessageQueue("FormatName:MULTICAST=234.1.1.1:8001"))
{
while (true)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
for (var i = 0; i < 1000; i++)
{
SendMessage(helloQueue,
string.Format("{0}: msg:{1} hello world ", DateTime.UtcNow.Ticks, i));
}
stopWatch.Stop();
Console.ReadLine();
Console.WriteLine("====================================================");
Console.WriteLine("[MSMQ] done sending 1000 messages in " + stopWatch.ElapsedMilliseconds);
Console.WriteLine("[MSMQ] Sending reset counter to consumers.");
SendMessage(helloQueue, "reset");
Console.ReadLine();
}
}
Receiver:
int messagesReceived = 0;
var messages = new Queue<string>(5000);
var filePath = typeof(Subscriber).FullName + ".txt";
var path = #".\private$\hello-queue";
using (var helloQueue = new MessageQueue(path))
{
helloQueue.MulticastAddress = "234.1.1.1:8001";
while (true)
{
var message = helloQueue.Receive();
if (message == null)
return;
var reader = new StreamReader(message.BodyStream);
var body = reader.ReadToEnd();
messagesReceived += 1;
messages.Enqueue(body);
Console.WriteLine(" [MSMQ] {0} Received {1}", messagesReceived, body);
if (string.CompareOrdinal("reset", body) == 0)
{
messagesReceived = 0;
File.WriteAllText(filePath, body);
messages.Clear();
}
}
}
I added key in registry for multicastbind with IP showing in event log(not sure about this).
The MulticastAddress that we specify in queue, is it something specific or we can use anything in the range specified ?
This got resolved by just changing the port number. Rest was fine.
Related
Basically, I am supposed to retrieve a value from a Bluetooth LE skincare device. Among the services that the device has, the device has a configuration service, with two characteristics: one for reading/writing data, and another characteristic for reading and writing the configuration value.
I have the document that shows all the UUID's, their characteristics, properties, values etc. The configuration indexes are all listed in the file too, and preprogrammed in the device.
Goal: This is where I am stuck. One of the config indexes has a value of 12. I have to write the config index to the characteristic, and then in return, the program will read the data corresponding to the configuration index, and print the data on the terminal. I sent a value as 0C (12 in hex), and ended up with FFFFFFFFFFFFFFFFFFFF. It has to be a different value.
How can I achieve this goal?
This is the code that I have so far:
while (true)
{
if (device == null)
{
Thread.Sleep(200);
}
else
{
Console.WriteLine("Press any key to pair the device.");
Console.ReadKey();
Console.WriteLine();
BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
Console.WriteLine("Attempting to pair with device");
GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync();
if (result.Status == GattCommunicationStatus.Success)
{
var services = result.Services;
foreach (var service in services)
{
if (service.Uuid.ToString() == configSvc)
{
GattCharacteristicsResult charactiristicResult = await service.GetCharacteristicsAsync();
if (charactiristicResult.Status == GattCommunicationStatus.Success)
{
var characteristics = charactiristicResult.Characteristics;
foreach (var characteristic in characteristics)
{
GattReadResult rResult = await characteristic.ReadValueAsync();
GattCharacteristicProperties properties = characteristic.CharacteristicProperties;
if (properties.HasFlag(GattCharacteristicProperties.Write))
{
var writer = new DataWriter();
GattCommunicationStatus wResult = await characteristic.WriteValueAsync(writer.DetachBuffer());
if (characteristic.Uuid.ToString() == configIdxCt)
{
int psCalVal = 12;
//var startCommand = Encoding.ASCII.GetBytes(psCalVal.ToString());
//Console.WriteLine(startCommand[0]);
writer.WriteByte(0xc0);
if (wResult == GattCommunicationStatus.Success)
{
Console.WriteLine("message sent successfully");
}
else
{
Console.WriteLine("Error encountered on writing to characteristic!");
}
}
}
if(properties.HasFlag(GattCharacteristicProperties.Read))
{
if (rResult.Status == GattCommunicationStatus.Success)
{
if (characteristic.Uuid.ToString() == configValCt)
{
var reader = DataReader.FromBuffer(rResult.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
//Console.WriteLine(input[0]);
Console.WriteLine("Data: ");
string psCArrayWDash = BitConverter.ToString(input) + " ";
string psCArray = psCArrayWDash.Replace("-", "").ToLower();
Console.WriteLine(psCArray);
}
if (characteristic.Uuid.ToString() == measurementCt)
{
Console.WriteLine("Read");
var reader = DataReader.FromBuffer(rResult.Value);
byte[] input = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(input);
Console.WriteLine("Data: ");
for (int i = 0; i < input.Length; i++)
Console.WriteLine(input[i].ToString() + " ");
}
}
else
Console.WriteLine("ERROR");
}
}
}
}
}
}
else
Console.WriteLine("Please, make sure the device is connected, and try again.");
}
}
deviceWatcher.Stop();
I need to grab all messages in a chat. I use C# and the TLSharp library.
I authrized, got the token etc. successfully.
But when I'm trying to get the messages in a loop, I'm going to an infinite loop.
So the text with the results is never appeared in the textbox.
I'd like to know what I'm doing wrong and how to fix it. Thanks.
using TeleSharp.TL;
using TeleSharp.TL.Messages;
using TLSharp.Core;
//using other standard...
//code for authorization etc. is skipped
int VKFID = 1175259547; //ID of the chat
int offset = 0;
int n = 1;
StringBuilder sb = new StringBuilder();
TelegramClient client = new TelegramClient(<key>, <hash>);
TLUser user;
private DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
private async void button3_Click(object sender, EventArgs e)
{
sb.Append("#\tDate\tTime\tMID\tTUID\tText" + Environment.NewLine);
TLDialogsSlice dialogs = (TLDialogsSlice)await client.GetUserDialogsAsync();
TLChannel chat = dialogs.Chats.Where(c => c.GetType() == typeof(TLChannel)).Cast<TLChannel>().FirstOrDefault(c => c.Id == VKFID);
TLInputPeerChannel inputPeer = new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = (long)chat.AccessHash };
while (true)
{
try
{
TLChannelMessages res = await client.SendRequestAsync<TLChannelMessages>
(new TLRequestGetHistory() { Peer = inputPeer, Limit = 1000, AddOffset = offset, OffsetId = 0 });
var msgs = res.Messages;
if (res.Count > offset)
{
offset += msgs.Count;
foreach (TLAbsMessage msg in msgs)
{
if (msg is TLMessage)
{
TLMessage message = msg as TLMessage;
sb.Append(n.ToString() + "\t" +
ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("dd'.'MM'.'yyyy") + "\t" +
ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("HH':'mm':'ss") + "\t" +
message.Id + "\t" + message.FromId + "\t" + message.Message + Environment.NewLine);
}
if (msg is TLMessageService)
continue;
n++;
}
Thread.Sleep(22000); //to avoid TelegramFloodException
}
else
break;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
break;
}
finally
{
await Task.Delay(22000); //to avoid TelegramFloodException
}
}
textBox2.Text = sb.ToString();
MessageBox.Show("Done");
}
There is now the WTelegramClient library, using the latest Telegram Client API protocol (connecting as a user, not bot).
The library is very complete but also very simple to use. Follow the README on GitHub for an easy introduction.
Connecting, finding your chat and retrieving all the messages can be done like this:
using TL;
using System.Linq;
const int TargetChatId = 1175259547;
using var client = new WTelegram.Client(); // or Client(Environment.GetEnvironmentVariable)
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
InputPeer peer = chats.chats.First(chat => chat.ID == TargetChatId);
for (int offset = 0; ;)
{
var messagesBase = await client.Messages_GetHistory(peer, 0, default, offset, 1000, 0, 0, 0);
if (messagesBase is not Messages_ChannelMessages channelMessages) break;
foreach (var msgBase in channelMessages.messages)
if (msgBase is Message msg)
{
// process the message
}
offset += channelMessages.messages.Length;
if (offset >= channelMessages.count) break;
}
Could you try to refresh your textbox before Thead.Sleep(22000)?
textBox2.Text += sb.ToString();
Application.DoEvents();
Thread.Sleep(22000);
Other way of doing this could be using a BackgroundWorker in the same way as it is used managing a ProgressBar.
I am doing some performance tests on ZeroMQ in order to compare it with others like RabbitMQ and ActiveMQ.
In my broadcast tests and to avoid "The Dynamic Discovery Problem" as referred by ZeroMQ documentation I have used a proxy. In my scenario, I am using 50 concurrent publishers each one sending 500 messages with 1ms delay between sends. Each message is then read by 50 subscribers. And as I said I am losing messages, each of the subscribers should receive a total of 25000 messages and they are each receiving between 5000 and 10000 messages only.
I am using Windows and C# .Net client clrzmq4 (4.1.0.31).
I have already tried some solutions that I found on other posts:
I have set linger to TimeSpan.MaxValue
I have set ReceiveHighWatermark to 0 (as it is presented as infinite, but I have tried also Int32.MaxValue)
I have set checked for slow start receivers, I made receivers start some seconds before publishers
I had to make sure that no garbage collection is made to the socket instances (linger should do it but to make sure)
I have a similar scenario (with similar logic) using NetMQ and it works fine. The other scenario does not use security though and this one does (and that's also the reason why I use clrzmq in this one because I need client authentication with certificates that is not yet possible on NetMQ).
EDIT:
public class MCVEPublisher
{
public void publish(int numberOfMessages)
{
string topic = "TopicA";
ZContext ZContext = ZContext.Create();
ZSocket publisher = new ZSocket(ZContext, ZSocketType.PUB);
//Security
// Create or load certificates
ZCert serverCert = Main.GetOrCreateCert("publisher");
var actor = new ZActor(ZContext, ZAuth.Action, null);
actor.Start();
// send CURVE settings to ZAuth
actor.Frontend.Send(new ZFrame("VERBOSE"));
actor.Frontend.Send(new ZMessage(new List<ZFrame>()
{ new ZFrame("ALLOW"), new ZFrame("127.0.0.1") }));
actor.Frontend.Send(new ZMessage(new List<ZFrame>()
{ new ZFrame("CURVE"), new ZFrame(".curve") }));
publisher.CurvePublicKey = serverCert.PublicKey;
publisher.CurveSecretKey = serverCert.SecretKey;
publisher.CurveServer = true;
publisher.Linger = TimeSpan.MaxValue;
publisher.ReceiveHighWatermark = Int32.MaxValue;
publisher.Connect("tcp://127.0.0.1:5678");
Thread.Sleep(3500);
for (int i = 0; i < numberOfMessages; i++)
{
Thread.Sleep(1);
var update = $"{topic} {"message"}";
using (var updateFrame = new ZFrame(update))
{
publisher.Send(updateFrame);
}
}
//just to make sure it does not end instantly
Thread.Sleep(60000);
//just to make sure publisher is not garbage collected
ulong Affinity = publisher.Affinity;
}
}
public class MCVESubscriber
{
private ZSocket subscriber;
private List<string> prints = new List<string>();
public void read()
{
string topic = "TopicA";
var context = new ZContext();
subscriber = new ZSocket(context, ZSocketType.SUB);
//Security
ZCert serverCert = Main.GetOrCreateCert("xpub");
ZCert clientCert = Main.GetOrCreateCert("subscriber");
subscriber.CurvePublicKey = clientCert.PublicKey;
subscriber.CurveSecretKey = clientCert.SecretKey;
subscriber.CurveServer = true;
subscriber.CurveServerKey = serverCert.PublicKey;
subscriber.Linger = TimeSpan.MaxValue;
subscriber.ReceiveHighWatermark = Int32.MaxValue;
// Connect
subscriber.Connect("tcp://127.0.0.1:1234");
subscriber.Subscribe(topic);
while (true)
{
using (var replyFrame = subscriber.ReceiveFrame())
{
string messageReceived = replyFrame.ReadString();
messageReceived = Convert.ToString(messageReceived.Split(' ')[1]);
prints.Add(messageReceived);
}
}
}
public void PrintMessages()
{
Console.WriteLine("printing " + prints.Count);
}
}
public class Main
{
static void Main(string[] args)
{
broadcast(500, 50, 50, 30000);
}
public static void broadcast(int numberOfMessages, int numberOfPublishers, int numberOfSubscribers, int timeOfRun)
{
new Thread(() =>
{
using (var context = new ZContext())
using (var xsubSocket = new ZSocket(context, ZSocketType.XSUB))
using (var xpubSocket = new ZSocket(context, ZSocketType.XPUB))
{
//Security
ZCert serverCert = GetOrCreateCert("publisher");
ZCert clientCert = GetOrCreateCert("xsub");
xsubSocket.CurvePublicKey = clientCert.PublicKey;
xsubSocket.CurveSecretKey = clientCert.SecretKey;
xsubSocket.CurveServer = true;
xsubSocket.CurveServerKey = serverCert.PublicKey;
xsubSocket.Linger = TimeSpan.MaxValue;
xsubSocket.ReceiveHighWatermark = Int32.MaxValue;
xsubSocket.Bind("tcp://*:5678");
//Security
serverCert = GetOrCreateCert("xpub");
var actor = new ZActor(ZAuth.Action0, null);
actor.Start();
// send CURVE settings to ZAuth
actor.Frontend.Send(new ZFrame("VERBOSE"));
actor.Frontend.Send(new ZMessage(new List<ZFrame>()
{ new ZFrame("ALLOW"), new ZFrame("127.0.0.1") }));
actor.Frontend.Send(new ZMessage(new List<ZFrame>()
{ new ZFrame("CURVE"), new ZFrame(".curve") }));
xpubSocket.CurvePublicKey = serverCert.PublicKey;
xpubSocket.CurveSecretKey = serverCert.SecretKey;
xpubSocket.CurveServer = true;
xpubSocket.Linger = TimeSpan.MaxValue;
xpubSocket.ReceiveHighWatermark = Int32.MaxValue;
xpubSocket.Bind("tcp://*:1234");
using (var subscription = ZFrame.Create(1))
{
subscription.Write(new byte[] { 0x1 }, 0, 1);
xpubSocket.Send(subscription);
}
Console.WriteLine("Intermediary started, and waiting for messages");
// proxy messages between frontend / backend
ZContext.Proxy(xsubSocket, xpubSocket);
Console.WriteLine("end of proxy");
//just to make sure it does not end instantly
Thread.Sleep(60000);
//just to make sure xpubSocket and xsubSocket are not garbage collected
ulong Affinity = xpubSocket.Affinity;
int ReceiveHighWatermark = xsubSocket.ReceiveHighWatermark;
}
}).Start();
Thread.Sleep(5000); //to make sure proxy started
List<MCVESubscriber> Subscribers = new List<MCVESubscriber>();
for (int i = 0; i < numberOfSubscribers; i++)
{
MCVESubscriber ZeroMqSubscriber = new MCVESubscriber();
new Thread(() =>
{
ZeroMqSubscriber.read();
}).Start();
Subscribers.Add(ZeroMqSubscriber);
}
Thread.Sleep(10000);//to make sure all subscribers started
for (int i = 0; i < numberOfPublishers; i++)
{
MCVEPublisher ZeroMqPublisherBroadcast = new MCVEPublisher();
new Thread(() =>
{
ZeroMqPublisherBroadcast.publish(numberOfMessages);
}).Start();
}
Thread.Sleep(timeOfRun);
foreach (MCVESubscriber Subscriber in Subscribers)
{
Subscriber.PrintMessages();
}
}
public static ZCert GetOrCreateCert(string name, string curvpath = ".curve")
{
ZCert cert;
string keyfile = Path.Combine(curvpath, name + ".pub");
if (!File.Exists(keyfile))
{
cert = new ZCert();
Directory.CreateDirectory(curvpath);
cert.SetMeta("name", name);
cert.Save(keyfile);
}
else
{
cert = ZCert.Load(keyfile);
}
return cert;
}
}
This code also produces the expected number of messages when security is disabled, but when turned on it doesn't.
Does someone know another thing to check? Or has it happened to anyone before?
Thanks
I have the following code where I am attempting to queue loads of messages on my rabbitmq queue to test it and see if I can break it. I do not get why it is not working:
What I am trying to do in the loop is to make it post the message 4 times and then finish. What could be the error in this code?
Code:
using System;
using RabbitMQ.Client;
using System.Text;
class Send
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
// for (int myInt = 0; myInt < 699;)
int myInt = 1;
do
while (myInt <= 4)
{
// channel.QueueDeclare("test", false, false, false, null);
//int myInt = 0;
//while (myInt < 10) ;
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", "test", null, body);
Console.WriteLine(" [x] Sent {0}", message);
Console.Read();
//Environment.Exit(0);
return;
}
//myInt++;
}
}
}
}
I have updated the code to:
using System;
using RabbitMQ.Client;
using System.Text;
class Send
{
public static void Main()
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using (var connection = factory.CreateConnection())
{ for (int myInt = 100; myInt <= 100000 ; myInt++)
using (var channel = connection.CreateModel())
while (myInt <= 100000)
{
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", "hello", null, body);
Console.WriteLine(" [x] Sent {0}", message);
Console.Read();
myInt++;
}
//myInt++;
}
//myInt++;
//return;
// myInt++;
}
}
But it is still not working.
You put the return statement inside the while loop, which causes the program to terminate after one iteration of the loop. Also, you forgot to increment the variable myInt so you would be running into the problem of an infinite loop even if you move the return statement. In addition, you don't need the do keyword. Your while loop should look something like this:
while (myInt <= 4)
{
string message = "Hello World!";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("", "test", null, body);
Console.WriteLine(" [x] Sent {0}", message);
Console.Read();
myInt++;
}
And your return statement should be the last line in the Main function.
I'm currently developing a small server/client application for a personal project. The server is meant to be run in Linux under Mono while the client is being run from a Windows PC.
I have an issue where I am passing data to the server (In this case string value of "on" and "off") however an if statement is always returning a false value.
The code from the server is as follows
public void startServer() {
TcpListener listen = new TcpListener(serverIP, 10000);
listen.Start();
Console.Clear();
Console.WriteLine("IP Address = {0}", serverIP.ToString());
Console.WriteLine("Server is listening for connection");
Socket a = listen.AcceptSocket();
Console.WriteLine("Connection from {0}", a.RemoteEndPoint);
ASCIIEncoding respond = new ASCIIEncoding();
a.Send(respond.GetBytes("You are connected to LED Control Server"));
bool keepListening = true;
while (keepListening) {
byte[] b = new byte[1000];
a.Receive(b);
Console.WriteLine("Message Received from {0}, string: {1}", a.RemoteEndPoint, recData(b));
string serverMsg = procIns(recData(b));
a.Send(respond.GetBytes(serverMsg));
}
}
private string recData(byte[] b) //receiving data from the client {
int count = b.Length;
string message = "";
for (int a = 0; a < count; a++) {
message += Convert.ToChar(b[a]);
}
return message;
}
private string procIns(string instruction) {
string returnMsg;
Console.WriteLine(instruction.ToLower());
if (instruction.ToLower() == "on") {
FileGPIO gpio = new FileGPIO();
gpio.OutputPin(FileGPIO.enumPIN.gpio17, true);
returnMsg = "GPIO 17 1";
} else if (instruction.ToLower() == "off") {
FileGPIO gpio = new FileGPIO();
gpio.OutputPin(FileGPIO.enumPIN.gpio17, false);
returnMsg = "GPIO 17 0";
} else {
returnMsg = "Invalid Command";
}
return returnMsg;
}
The cause for the if statement in procIns method returning false is escaping me, if anyone could offer any advice I would appreciate it!
I would guess it would have to be padded spaces. Try this instead...
if (instruction.Trim().ToLower() == "on")
while (keepListening) {
byte[] b = new byte[1000];
int bytesRcvd = a.Receive(b);
Console.WriteLine("Message Received from {0}, string: {1}", a.RemoteEndPoint, recData(b));
string serverMsg = procIns(recData(b, bytesRcvd ));
a.Send(respond.GetBytes(serverMsg));
}
a.Receive(b) method returns number of bytes received. You can store the value in some variable and pass the variable to recData method.
private string recData(byte[] b, int bytesRcvd) {
string message = "";
for (int a = 0; a < bytesRcvd; a++) {
message += Convert.ToChar(b[a]);
}
return message;
}
The number of bytes received will help in truncating the extra values in byte array.