Send a XMPP message to an OpenFire room from the command line - c#

I'm having problems trying to send an XMPP message to a 'Room' in our OpenFire instance. The end result is for our CruiseControl.NET build server to be able to send success/failure messages to the appropriate 'Rooms' as an additional means of notification.
I'm using the Matrix XMPP library to create a Console Application in C# using VS2010. The idea was to create a simple .exe that I can wire up to CCNet and pass a few arguments into as required.
The code below is basically the sample code from the Matrix site/documentation which I have updated to point to a room.
static void Main(string[] args)
{
var xmppClient = new XmppClient
{
XmppDomain = "SERVER",
Username = "davidc",
Password = "*********"
};
xmppClient.OnRosterEnd += delegate
{
xmppClient.Send(new Message
{
To = "roomname#conference.SERVER",
From = "davidc#SERVER",
Type = MessageType.groupchat,
Body = "Just Testing the XMPP SDK"
});
};
xmppClient.Open();
Console.WriteLine("Press return key to exit the application");
Console.ReadLine();
xmppClient.Close();
}
I can send to an individual user (changing the To and Type accordingly) without any problems but changing the code to point to a room ends in silence! Is there some additional 'handshaking' that needs to be done to address a room?
I don't really have to use C# for the solution as long as it will run on a Windows Server.

You'll want to read XEP-0045, "Multi-User Chat". You need to enter the room before sending a message to it. For a quick fix, see section 7.1.1, which shows how to join a room using a simplified (older) protocol:
<presence
to='darkcave#chat.shakespeare.lit/thirdwitch'/>
For the newer protocol, include an extra x tag from section 7.1.2:
<presence
to='darkcave#chat.shakespeare.lit/thirdwitch'>
<x xmlns='http://jabber.org/protocol/muc'/>
</presence>
I don't know your library, but you'll want code something like:
xmppClient.Send(new Presence
{
To = "roomname#conference.SERVER/mynick",
});

Related

Communication between Python and C#

I have a Python backend running machine learning algorithms. I want to use the same backend for both an Excel plugin (C#) and a website. I want both interfaces to send my training data (thousands of lines of numbers in arrays) to the same Python application and retrieve the results in the form of another array up to a few thousand lines.
The website would fetch data from a SQL database and send that data to Python, while the Excel plugin would take the data that is in the current worksheet and send that data to Python. I need to be able to create numpy arrays in Python before continuing to process the data. Note that the website would be running on the same machine where the Python application resides. I still haven't decided what I will use to code the website, but I was leaning towards Node.js.
I have done some research and found a few options:
1- Named pipes
2- Sockets
3- RPC server such as gRPC or XML-RPC.
4- Writing the data to a file and reading it back in Python
5- Web Service
Note: I would need the Python "server" to be stateful and keep the session running between calls. So I would need to have a kind of daemon running, waiting for calls.
Which one would you experts recommend and why? I need flexibility to handle several parameters and also large arrays of numbers. Using IronPython is not an option because I am running Keras on Python, which apparently does not support IronPython.
I had the same problem recently.
I used a named pipe to transport data from python to my c# server, hope it helps you.
Python:
import win32pipe, win32file
class PipeServer():
def __init__(self, pipeName):
self.pipe = win32pipe.CreateNamedPipe(
r'\\.\pipe\\'+pipeName,
win32pipe.PIPE_ACCESS_OUTBOUND,
win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,
1, 65536, 65536,
0,
None)
#Carefull, this blocks until a connection is established
def connect(self):
win32pipe.ConnectNamedPipe(self.pipe, None)
#Message without tailing '\n'
def write(self, message):
win32file.WriteFile(self.pipe, message.encode()+b'\n')
def close(self):
win32file.CloseHandle(self.pipe)
t = PipeServer("CSServer")
t.connect()
t.write("Hello from Python :)")
t.write("Closing now...")
t.close()
For this code to work you need to install pywin32 (best choice is from binarys): https://github.com/mhammond/pywin32
C#-Server:
using System;
using System.IO;
using System.IO.Pipes;
class PipeClient
{
static void Main(string[] args)
{
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "CSServer", PipeDirection.In))
{
// Connect to the pipe or wait until the pipe is available.
Console.Write("Attempting to connect to pipe...");
pipeClient.Connect();
Console.WriteLine("Connected to pipe.");
Console.WriteLine("There are currently {0} pipe server instances open.",
pipeClient.NumberOfServerInstances);
using (StreamReader sr = new StreamReader(pipeClient))
{
// Display the read text to the console
string temp;
while ((temp = sr.ReadLine()) != null)
{
Console.WriteLine("Received from server: {0}", temp);
}
}
}
Console.Write("Press Enter to continue...");
Console.ReadLine();
}
}
You can use Python for .NET (Python.NET). It may require some changes to your code, but then it should work very well, once everything is in good shape.
Python.NET allows two-way communication between CPython and CLR.
Let me give you a neat and quick recipe, in the form of example code.
There are basically two ways to tie python in the backend of C# (or a C# winform app or gui or something similar).
Method1: Iron Python. In this method you install a .net package in your visual studio called IronPython. I would not prefer this, because assuming your machine learning model uses keras or a lot of other libraries. It would be another quest to get you installations ready and working in IronPython. And most importantly, it is not as good as your common virtual env or conda environment.
Method2: (The Good Method): Create a Custom Process in your C# that takes arguments from your GUI, knows the path to your script and your python env. Using all these things, it calls your python code exactly the way you would call it in your terminal and pass arguments to it.
Now the tasty example code (I have used this simple trick and it always helps make my black screen python stuff look good with the cover of C# apps).
Python Part
import sys
a = sys.argv[1]
b = sys.argv[2]
print("The Sum = ", float(a)+float(b))
The C# Part
So here is the python process/function that you need to call on the click event of your sum button in the application
static void PythonProcess()
{
//1) Create Process Info
var psi = new ProcessStartInfo();
//Conda Env Path
psi.FileName = #"C:\Users\jd\.conda\pkgs\py\python.exe";
//2) Provide Script and the Arguments
var script = #"C:\Users\jd\Desktop\script.py";
var a = "15";
var b = "18";
psi.Arguments = $"\"{script}\" \"{a}\" \"{b}\"";
//3) Process Configuration
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
//4) Execute Process and get Output.
var errors = "";
var results = "";
using(var process = Process.Start(psi))
{
errors = process.StandardError.ReadToEnd();
results = process.StandardOutput.ReadToEnd();
}
//5) Display Output
Console.WriteLine("ERRORS: ");
Console.WriteLine(errors);
Console.WriteLine();
Console.WriteLine("RESULTS: ");
Console.WriteLine(results);
}
Calling Python from C# is easily possible via Pyrolite where your Python code is running as a Pyro4 server. It should be fast enough to handle "large arrays of numbers" however you didn't specify any performance constraints.
I had the same issue and seem to end up with named pipes. Here is a nice example of how to set it up to talk C# => Python, assuming C# is the server.
It can use the same way to talk back or just Python.net to call directly through CLR as shown here. I use the latter.

Unable to communicate between actors in Akka.Cluster

I am having some problems in communicating between actors in Cluster.
My test project has this structure below.
TestJob [C# Console Project]
TestJobService.cs
TestJobActor
MainProject [C# Console Project] //Note: I configured this service as a seed node. I didn't use lighthouse.
MainService
JobManagerActor
Note: I don't want to put actors in Shared project or Main project. The actors that are supposed to do a test job should be under "TestJob" project.
I already followed this article http://getakka.net/docs/clustering/cluster-overview and video. I did enable Akka.Cluster based on the article. I am able to run both console projects but when I tried to "tell" from JobManagerActor to TestJobActor, it doesn't work. No error but doesn't work.
I have this config in MainProject.
actor {
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
deployment {
/TestJobAActor {
router = consistent-hashing-group
routees.paths = ["/user/TestJobAActor"]
virtual-nodes-factor = 8
cluster {
enabled = on
max-nr-of-instances-per-node = 2
allow-local-routees = off
use-role = backend
}
}
}
}
Here is the code that I use for sending the message.
var backendRouter = Context.ActorOf(Props.Empty.WithRouter(new ClusterRouterGroup(new ConsistentHashingGroup("/user/TestJobAActor"),new ClusterRouterGroupSettings(10, false, "backend", ImmutableHashSet.Create("/user/TestJobAActor")))));
backendRouter.Tell("Yo yo!");
What am I missing? Thanks in advance.
Note: My test project with similar structure can be found here https://github.com/michaelsync/APMDemo . (VS2015 project)
One more question: Can we still use the actor selection when using cluster?
var actorSelection = Context.ActorSelection("akka.tcp://MyBackendProcessingSystem#127.0.0.1:2553/user/BackEndJobAActor"); //This can come from Model
actorSelection.Tell("Yo yo!");
No worries!
I managed to fix it myself. You can see the fixes in my temp repo https://github.com/michaelsync/APMDemo/tree/allinoneproject.
The problem was that I didn't know I need to use IConsistentHashable for sending message in consistent-route. I keep on sending the string and didn't work.
local route was off.

asp.net c# connecting to putty ssh and running a command line like status

ok folks i have seen alot of questions about this but none that i can use or understand
What i am attempting to do is connect to putty from asp.net c# and then run a command to get the status
i will then use the results to draw a report every 3 seconds and display it on my web page
this is the first time a have attempted this so i am rather ignorant
private void connect_putty()
{
Process sh = new Process();
sh.StartInfo.FileName = "Putty.exe";
sh.StartInfo.UseShellExecute = false;
sh.StartInfo.CreateNoWindow = false;
sh.StartInfo.Arguments = "";
}
what i presently have which to be honest is pathetic any help will be appreciated
Thanks in advance
I would suggest using Tamir.SSH.
This will allow you to do everything from C#.
Also, I wrote some code once, it may help you.
https://github.com/daneb/Push2Linux/blob/master/Form1.cs
Sample:
SshShell ssh; // create our shell
ssh = new SshShell(aHost.host, aHost.username, aHost.password);
// Command Output
string commandoutput = string.Empty;
// Remove Terminal Emulation Characters
ssh.RemoveTerminalEmulationCharacters = true;
// Connect to the remote server
ssh.Connect();
//Specify the character that denotes the end of response
commandoutput = ssh.Expect(promptRegex);
PuTTY includes all the terminal emulation (hence the name), so assuming you mean 'connect via ssh', instead of the putty app specifically, then SSH.NET and SharpSSH are 2 good choices.
See this related question: C# send a simple SSH command

Making a windows service from a console application

Is it possible to make a windows service from a console application.
In fact, i made a console application that sends emails to persons from a database but when I tried to make a service with almost the same code it didn't work. After installing it emails aren't nomore sent. So, I want to transform my console application into a service if there is a way because I want to send them automatically and I don't want to use task sheduler.
Here is my console application main
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress(ConfigurationManager.AppSettings["email"]);
mail.Subject = "Rappel délai tâche";
SmtpClient client = new SmtpClient(ConfigurationManager.AppSettings["domaine"]);
client.EnableSsl = true;
client.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["email"], ConfigurationManager.AppSettings["password"]);
BDGestionEntities bd = new BDGestionEntities();
TimeSpan diff;
DateTime aujourdhui = DateTime.Today;
List <tache> taches = bd.taches.ToList();
foreach (var k in taches)
{
Console.WriteLine(k.nom_tache);
diff = k.date_fin.Subtract(aujourdhui);
int datediff = Convert.ToInt32(diff.TotalDays);
if (datediff <= 2)
{
mail.To.Add(k.utilisateur.email);
mail.Body = "Bonjour, " + k.utilisateur.nom + " " + k.utilisateur.prenom +
"\n\nNous vous envoyons le présent mail pour vous rappeler que la tâche \"" + k.nom_tache + "\" qui vous est accordée touchera à sa fin d'ici deux jours.\nVeuillez respecter le délai. \n\n Bien cordialement.";
try
{
client.Send(mail);
Console.WriteLine("Email envoyé");
}
catch (Exception ex)
{
Console.Write(ex.Message);
}
}
}
}
In fact I'm using a model with ado .net inorder to access to my database
Rather than try and convert it straight off, I'd try writing a very simple service first to get a feel for how it works. Maybe something simple like writing the date and time to a file every 5 minutes. You could then try adding your code to the service body.
Obviously you'll want to avoid anything that writes to the screen. This should be written to either a log or the event viewer.
The basic code will work, you just need to move it into the service portion - however it will probably crash at the console write lines, because services by default dont have access to screen, and arent allocated a console.
If you use visual studio it will template you a service. But, you can do pretty much the same work - I actually changed my service so I can run it from command line if it had the parameter /console it allocated a console so it could use it and I can debug it etc.
I found the solution for that. In fact, it was just a connection problem and all I had to do was to add permissions to the service in order to let it access the database. Thank you everyone.
Windows services have a bit more to them than console applications. You can transform it into one if you have the source, or you can use an existing service wrapper. If you want to transform your application you may want to start with one of the following
http://www.codeproject.com/Articles/14353/Creating-a-Basic-Windows-Service-in-C
http://www.c-sharpcorner.com/uploadfile/mahesh/window_service11262005045007am/window_service.aspx
If you want to use a service wrapper this may be interesting, or other products like it.
The Windows 2003 Server Resource Kit provides two utilities that allow you to create a Windows user-defined service for Windows applications.
Instrsrv.exe installs and removes system services and Srvany.exe allows any Windows application to run as a service.
This Microsoft Support article shows how.

verbot 5 sdk - loading KnowledgeBases

I'm looking for help from anyone who's worked with the verbot sdk.
I'm making a program that I want to use the LearnedKnowledge.vkb, Teacher.vkb, and any standard bot (julia, for example). Those who've used this before will know that with the rules in Teacher, you can essentially write responses to things that the bot doesn't understand, and train it on the fly.
I'm planning on using speech recognition and text-to-speech, but my problem right now is that after I load the knowledgebases, I can't seem to get any response from the bot.
Here's what I have: The Verbot5Library.dll, from verbots.sourceforge.net (I got the editor and player too, to make sure the files were working). In my program, I set up the variables as such:
Verbot5Engine verbot = new Verbot5Engine();
KnowledgeBase kb = new KnowledgeBase();
KnowledgeBaseItem kbi = new KnowledgeBaseItem();
State state = new State();
XMLToolbox xmlToolboxKB = new XMLToolbox(typeof(KnowledgeBase));
Then I initialize the verbot engine and load the kbs:
// using the xmlToolboxKB method I saw in this forum: http://www.verbots.com/forums/viewtopic.php?t=2984
kbi.Fullpath = #"C:\\[full path to kb...]\\";
kbi.Filename = "LearnedKnowledge.vkb";
kb = (KnowledgeBase)xmlToolboxKB.LoadXML(kbi.Fullpath + kbi.Filename);
verbot.AddKnowledgeBase(kb, kbi);
kbi.Filename = "julia.vkb";
kb = (KnowledgeBase)xmlToolboxKB.LoadXML(kbi.Fullpath + kbi.Filename);
verbot.AddKnowledgeBase(kb, kbi);
//trying to use LoadKnowledgeBase and LoadCompiledKnowledgeBase methods: verbot.LoadKnowledgeBase("C:\\[full path to kb...]\\LearnedKnowledge.vkb");
//verbot.LoadCompiledKnowledgeBase("C:\\[full path...]\\julia.ckb");
//verbot.LoadCompiledKnowledgeBase("C:\\[full path...]\\Teacher.ckb");
// set up state
state.CurrentKBs.Add("C:\\[full path...]\\LearnedKnowledge.vkb");
state.CurrentKBs.Add("C:\\[full path...]\\Teacher.vkb");
state.CurrentKBs.Add("C:\\[full path...]\\julia.ckb");
Finally, I attempt to get a response from the verbot engine:
Reply reply = verbot.GetReply("hello", state);
if (reply != null)
Console.WriteLine(reply.AgentText);
else
Console.WriteLine("No reply found.");
I know julia has a response for "hello", as I've tested it with the editor. But all it ever returns is "No reply found". This code has been taken from the example console program in the SDK download (as very little documentation is available). That's why I need some pointers from someone who's familiar with the SDK.
Am I not loading the KBs correctly? Do they all need to be compiled (.ckb) instead of the XML files (.vkb)? I've used the verbot.OnKnowledgeBaseLoadError event handler and I get no errors. I even removed the resource file Default.vsn needed to load the Teacher, and it throws an error when trying to load it so I'm pretty sure it's all loading correctly. So why do I always get "No reply found"?
resolved: see http://www.verbots.com/forums/viewtopic.php?p=13021#13021

Categories

Resources