Rabbit MQTT client in PHP? - phpmqtt

I am new to MQTT. Can anyone help how to use Rabbitmq mqtt in PHP, I have MQTT broker in cloud so I want to develop based on PHP in my local system. Any library we want to download? Can anyone help on that in Ubuntu?

You can use the client lib: https://github.com/bluerhinos/phpMQTT as described here: https://www.cloudamqp.com/docs/php_mqtt.html
Publisher
require("phpMQTT.php");
$host = "hostname";
$port = port;
$username = "username";
$password = "password";
$message = "Hello CloudAMQP MQTT!";
//MQTT client id to use for the device. "" will generate a client id automatically
$mqtt = new phpMQTT($host, $port, "ClientID".rand());
if ($mqtt->connect(true,NULL,$username,$password)) {
$mqtt->publish("topic",$message, 0);
$mqtt->close();
}else{
echo "Fail or time out";
}
Subscriber
require("phpMQTT.php");
$host = "hostname";
$port = port;
$username = "username";
$password = "password";
$mqtt = new phpMQTT($host, $port, "ClientID".rand());
if(!$mqtt->connect(true,NULL,$username,$password)){
exit(1);
}
//currently subscribed topics
$topics['topic'] = array("qos"=>0, "function"=>"procmsg");
$mqtt->subscribe($topics,0);
while($mqtt->proc()){
}
$mqtt->close();
function procmsg($topic,$msg){
echo "Msg Recieved: $msg";
}
MQTT is enabled by default on all CloudAMQP servers, so there is no need to enable the MQTT plugin if you are using CloudAMQP as MQTT broker. If not, you need to enable this plugin: https://www.rabbitmq.com/mqtt.html

Related

Unable to Connect to Rabbit MQ

I am using amazon service and created rabbitmq broker now from the DOT NET code i am trying to connect to this broker.
var factory = new ConnectionFactory
{
Uri = new Uri("amqps://it:Password#hostname:5671")
};
var connection = factory.CreateConnection();
I am struggle here to get connection getting below error :
None of the specified endpoints were reachable
at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
Update:
It seems your client wants to connect using TLS/SSL (your uri specifies the protocol "amqps" and the port 5671).
Try enabling TLS/SSL:
var factory = new ConnectionFactory {
UserName = userName,
Password = password,
VirtualHost = "/",
HostName = hostName,
Port = port,
Ssl = new SslOption
{ Enabled = true, // <--------
ServerName = hostName }
};
The (JVM based) guide shows how to configure the connection factory. It sets the credentials on the factory, not in the URI:
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername(username); // <----------
factory.setPassword(password); // <----------
//Replace the URL with your information
factory.setHost("b-c8352341-ec91-4a78-ad9c-a43f23d325bb.mq.us-west-2.amazonaws.com");
factory.setPort(5671);
// Allows client to establish a connection over TLS
factory.useSslProtocol()
// Create a connection
Connection conn = factory.newConnection();
(This needs to be translated to the corresponding .NET code)

How can I get the IP of a client device connected through terminal services?

Problem
I need to get the client IP of a user connected through RDP/TS from an ASP site.
Sample data
The server hosting the site is at 10.1.0.1.
The user's machine is connected to a terminal server whose IP is 10.2.0.1.
The user is at a physical client whose IP is 10.3.0.1.
Attempted solutions
I have tried pulling the data from headers.
Request.ServerVariables["REMOTE_HOST"] 10.2.0.1
Request.ServerVariables["HTTP_X_FORWARDED_FOR"] [blank]
Request.ServerVariables["REMOTE_ADDR"] 10.2.0.1
Request.UserHostAddress 10.2.0.1
I also tried these methods.
public static string getIP()
{
string ips = string.Empty;
string hostName = HttpContext.Current.Request.UserHostAddress.ToString();
IPAddress[] ipAddresses = Dns.GetHostAddresses(hostName);
foreach (IPAddress ipAddress in ipAddresses)
{
ips += ipAddress + "<br />";
}
return ips;
}
Returns 10.2.0.1.
public static string GetIPAddress()
{
string ipAddress = "";
string Hostname = Environment.MachineName;
IPHostEntry Host = Dns.GetHostEntry(Hostname);
foreach (IPAddress IP in Host.AddressList)
{
if (IP.AddressFamily == AddressFamily.InterNetwork)
{
ipAddress= Convert.ToString(IP);
}
}
return ipAddress;
}
Returns 10.1.0.1.
Question
Is it possible to get 10.3.0.1 returned since there is an extra hop from the user's physical client through the TS to the web server? Is this possible with another language--e.g., PHP?

149.xxx.xxx.xxx is my address exception (C#, ASP.NET CORE 2.0, SMTP-client, MailKit)

Good day, dear collegues!
I'm trying to send email using SMTP-server, created by my collegue. I'm using .net core 2.0 this Identity.
When I run my application at debug-mode using my own computer -- it works perfectly.
When I run the same app on hosting it throws this exception:
SmtpCommandException: 149.xxx.xxx.xxx is my address
MailKit.Net.Smtp.SmtpClient.OnSenderNotAccepted(MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
the hosting and the smtp-server have the same IP-address and work at the same computer.
I'm sure, that exception of form "149.xxx.xxx.xxx is my address" means, that smtp-server thinks, I'm spamer, trying to use its IP to be "whitelisted" -- and this server blocks me.
I've found this:
HELO is faked interface address
Type: forgery
Some spammers put the server's interface address they connect to in their HELO, maybe asuming it is whitelisted or something.
drop condition = ${if eq{[$interface_address]}{$sender_helo_name}}
message = $interface_address is my address
But the same hosting has many other web-applications, they don't have a problem with connection to the local server.
public async Task SendEmailAsync(string email, string subject, string message)
{
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress("No reply", "XX#XXXX.XXX"));
emailMessage.To.Add(new MailboxAddress("", email));
emailMessage.Subject = subject;
emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html)
{
Text = message
};
using (var client = new SmtpClient())
{
await client.ConnectAsync("localhost", 25, SecureSocketOptions.None);
await client.AuthenticateAsync("XX#XXXX.XXX", "Password");
await client.SendAsync(emailMessage);
await client.DisconnectAsync(true);
}
}
I tried to use its address instead of "localhost". But it throws the same exception.
What should I do? How to say a smtp-server that I'm not spamer, that I'm just physically situated on its IP-address, on the same computer?
Yes, now I've done it!
I needed to use direct connection to local mail server (without SMTP, this is very important).
How to implement direct connection? My web-server uses Linux Ubuntu system. So I needed to use the Shell (Ubuntu terminal).
Firstly I've tested it manually: when I type "sendmail" (command for direct usage of local mail server) it requires email of recipient.
And I needed to type in terminal:
$ sendmail xxx#mail.com
subject:My subject //this is new line
to:xxx#mail.com // this is new line
from:kkk#mydomain.com // this is new line
Here I can write many lines of my letter's body.
. // this is the point in new line (the only symbol) to show this is end of the letter. Next keyboard "enter" means to send finally.
To use these commands, I needed to create new process (the same as to give command "sendmail").
So, instead of this all:
var emailMessage = new MimeMessage();
emailMessage.From.Add(new MailboxAddress("No reply", "XX#XXXX.XXX"));
emailMessage.To.Add(new MailboxAddress("", email));
emailMessage.Subject = subject;
emailMessage.Body = new TextPart(MimeKit.Text.TextFormat.Html)
{
Text = message
};
using (var client = new SmtpClient())
{
await client.ConnectAsync("localhost", 25, SecureSocketOptions.None);
await client.AuthenticateAsync("XX#XXXX.XXX", "Password");
await client.SendAsync(emailMessage);
await client.DisconnectAsync(true);
}
I've just inserted
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "sendmail";
info.Arguments = $"{email}";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("from:kkk#mydomain.com");
sw.WriteLine($"to:{email}");
sw.WriteLine($"subject:{subject}");
sw.WriteLine(message);
sw.WriteLine(".");
}
}
p.WaitForExit();

CertEnroll 509PrivateKey KeyProtection password not working when using client certificate in W8 W10

We have a process where our clients sign up for X509 client certificate through CertEnroll.
It works, but now one of our clients like to add one extra layer of security, so we added password to the certificate.
User is asked for password when creating the certificate and then have use the password every time the certificate is being used.
It works both ways in Windows 7, but in Windows 8.1 / 10
Browsers are all IE 11.
In Windows 8.1 / 10 the password is asked for when user is applying for the certificate, but when the certificate then is going to be used the password is not asked for.
Hope someone have a clue what is going on here.
Here is the javascript creating the certificate request.
function doSubmit() {
var PublicKeyInfo =''
var request;
request = document.forms(0)
//
// other stuff
//
try {
// Variables
var objCSP = request.Enroll.CreateObject("X509Enrollment.CCspInformation");
var objCSPs = request.Enroll.CreateObject("X509Enrollment.CCspInformations");
var objPrivateKey = request.Enroll.CreateObject("X509Enrollment.CX509PrivateKey");
var objRequest = request.Enroll.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10")
var objObjectIds = request.Enroll.CreateObject("X509Enrollment.CObjectIds");
var objObjectId = request.Enroll.CreateObject("X509Enrollment.CObjectId");
var objX509ExtensionEnhancedKeyUsage = request.Enroll.CreateObject("X509Enrollment.CX509ExtensionEnhancedKeyUsage");
var objExtensionTemplate = request.Enroll.CreateObject("X509Enrollment.CX509ExtensionTemplateName")
var objDn = request.Enroll.CreateObject("X509Enrollment.CX500DistinguishedName")
var objEnroll = request.Enroll.CreateObject("X509Enrollment.CX509Enrollment")
// Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
objCSP.InitializeFromName("Microsoft Enhanced Cryptographic Provider v1.0");
// Add this CSP object to the CSP collection object
objCSPs.Add(objCSP);
objPrivateKey.Length = "2048";
objPrivateKey.KeySpec = 1;
//objPrivateKey.ExportPolicy = 1; // Possible to export PrivateKey
//Force password when request for cert and password when cert is used
objPrivateKey.KeyProtection = 2; // XCN_NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG
// Provide the CSP collection object (in this case containing only 1 CSP object)
// to the private key object
objPrivateKey.CspInformations = objCSPs;
// Initialize P10 based on private key
objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); // context user = 1
// 1.3.6.1.5.5.7.3.2 Oid - Extension
objObjectId.InitializeFromValue("1.3.6.1.5.5.7.3.2");
objObjectIds.Add(objObjectId);
objX509ExtensionEnhancedKeyUsage.InitializeEncode(objObjectIds);
objRequest.X509Extensions.Add(objX509ExtensionEnhancedKeyUsage);
objDn.Encode("CN=xxxxxx", 0); // XCN_CERT_NAME_STR_NONE = 0
objRequest.Subject = objDn;
// Enroll
objEnroll.InitializeFromRequest(objRequest);
var pkcs10 = objEnroll.CreateRequest(3); // XCN_CRYPT_STRING_BASE64REQUESTHEADER = 3
request.PublicKeyInfo.value = pkcs10
} catch (ex) {
alert( ex.description + "\n" + ex.error );
return false;
}
request.submit()
}
Problem solved.
When installing the issued certificates it did not work if I installed them as "Local Computer", but if installed as "Current User" it worked for W8.1 / W10 also.

Communication with GPRS module using C#, with TCP

I have searched a lot for this but could not find any specific answer that applies to my case. I have made device using GPS module and GSM/GPRS module with Arduino Mega 2560, and it sends me the location through SMS. Now I want to get the location parameters using GPRS. I have in mind to use TCP. I will send data through AT Commands from GPRS module, but I am confused on how to make a server on C#. I know that I would be needing a static/public IP for this. But I don't know how to get the public IP, and start receiving data which I send from GPRS module. Please please I need help because I am a beginner in Client/Server programming, and I am working on my final year project. Many thanks in advance!
please take a look at this TCP server and client example.
You will need a public static IP address. That is something you have to ask your broadband provider, and they will explain you the available options they have, probably you will have to pay extra money. You can use your current public IP address, that will be probably dynamic, but they don't use to change way to often, so whenever you are unable to connect, you will have to check if the IP changed or not, and set the new one.
This video series maybe a good introduction: https://vimeo.com/38103518
Here is the Server Code:
class Server
{
TcpListener server = null;
public Server(string ip, int port)
{
IPAddress localAddr = IPAddress.Parse(ip);
server = new TcpListener(localAddr, port);
server.Start();
StartListener();
}
public void StartListener()
{
try
{
while (true)
{
Console.WriteLine("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
Thread t = new Thread(new ParameterizedThreadStart(HandleDeivce));
t.Start(client);
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
}
public void HandleDeivce(Object obj)
{
TcpClient client = (TcpClient)obj;
NetworkStream stream = client.GetStream();
string data = null;
Byte[] bytes = new Byte[256];
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("{1}: Received: {0}", data, Thread.CurrentThread.ManagedThreadId);
if (data.StartsWith("##"))
{
data = "LOAD";
}
else
{
data = "ON";
}
byte[] msg = Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
Console.WriteLine("{1}: Sent: {0}", data, Thread.CurrentThread.ManagedThreadId);
}
client.Close();
}
}

Resources