Guten Abend,
ich habe mir eine kleine Consolen Anwendung geschrieben die mithilfe einiger Befehle Dienste auf dem System steuert.
Nun möchte ich diese Anwendung aber auch von Außerhalb wie eines PHP Skripts ansprechen und die Anwendung soll auch eine Statusmeldung zurückliefern.
Ich hab das ganze mit TCP/IP versucht allerdings bekommt das PHP Skript immer einen Timeout, welche möglichkeiten gäbe es denn noch um ein PHP Skript mit einer Consolen Anwendung Kommunizieren zu lassen wo es auch möglich ist dem Skript direkt einen Status oder eine Meldung zurückzuliefern außer via TCP/IP.
Gibt es da nicht irgendwie was mit XML/RPC oder irgendwie sowas?
Danke für eure Hilfe.
Gruß
Patrcik
Hallo NewCannon,
grundsätzlich ist da jeder Art der IPC (inter-process-communication) möglich. Hier würde sich WCF anbieten und zwar so, dass die Consolen-Anwendung als Host für den Service fungiert. Das PHP-Script wäre demnach der Client.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Hallo,
TCP/IP muss prinzipiell funktionieren. Tut es das nicht, gibt's noch ein systematisches, aber kein grundsätzliches Problem.
WCF scheint für mich die passende Lösung zu sein. Allerdings finde ich in Visual Studio 2013 Desktop Edition den WCF Service nicht.
Hallo NewCannon,
meinst du die Projekt-Vorlage oder was? Das ist nicht (unbedingt) nötig. Füge bei deinem bestehen Consolen-Projekt einfach einen Verweis zu System.ServiceModel hinzu und schreib den Code für WCF wie du ihn sicherlich schon gesehen hast.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
So, habe mich nun mal dran gesetzt den WCF Host zu erstellen gab soweit auch keine Problme ich habe den Code:
using(ServiceHost host = new ServiceHost(typeof(WittyBots_Service.BotHost)))
{
host.Open();
Console.WriteLine("Service Host started!");
}
Die App.config schaut so aus:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<services>
<service name="WittyBots_Service.BotHost" behaviorConfiguration="maxBehavior">
<endpoint address="BotService" binding="basicHttpBinding" contract="WittyBots_Service.IBotHost"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="maxBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Er gibt mir in der Console auch Service Host started aus aber wen ich nun im Browser die Adresse localhost:8080 eingebe unter der ich den Service gestartet habe bekomme ich keine Service Webseite angezeigt wie ich es in einigen Tutorials über WCF gesehen habe. Mein Browser sagt nur ich habe kein Zugriff auf das Netzwerk.
Sind die Tutorials einfach nur veraltet und diese Service Webseite wird nicht mehr angezeigt in den neuen WCF Versionen oder habe ich einen Fehler in meinem Code?
Hallo NewCannon,
probier die Adresse http://localhost:8080/BotService - auf dieser ist das Http-Binding deklariert. Nur unter localhost:8080 läuft ja nix.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Leider kommt dort auch nix auch wen ich in einem Client Programm die adresse http://localhost:8080/BotService als Dienstverweis hinzufügen möchte kommt ein Fehler:
Fehlermeldung:
Fehler bei dem Versuch, Dienste unter "http://localhost:8080/BotService" zu finden.
Hallo NewCannon,
kannst du dein Projekt hier anhängen, dann schau ich es mir mal an.
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Das Archiv ist leider zu Groß zum Anhängen, daher habe ich es auf meinem Server hochgeladen: http://softwareelite.de/WittyBots.rar
Hab das ganze nun auch schonn mit Sockets probiert auch das funktioniert nicht erhalte immer ein Timeout der Server code schaut dabei so aus:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Premium_Bots
{
class Program
{
private static Socket sListener;
private static SocketPermission permission;
private static IPEndPoint ipEndPoint;
private static Socket handler;
static void Main(string[] args)
{
permission = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", SocketPermission.AllPorts);
IPHostEntry ipHost = Dns.GetHostEntry("");
IPAddress ipAddr = ipHost.AddressList[0];
ipEndPoint = new IPEndPoint(ipAddr, 4510);
sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sListener.Bind(ipEndPoint);
sListener.Listen(5);
AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
sListener.BeginAccept(aCallback, sListener);
Console.ReadLine();
}
public static void AcceptCallback(IAsyncResult ar)
{
Socket listener = null;
// A new Socket to handle remote host communication
Socket handler = null;
try
{
// Receiving byte array
byte[] buffer = new byte[1024];
// Get Listening Socket object
listener = (Socket)ar.AsyncState;
// Create a new socket
handler = listener.EndAccept(ar);
// Using the Nagle algorithm
handler.NoDelay = false;
// Creates one object array for passing data
object[] obj = new object[2];
obj[0] = buffer;
obj[1] = handler;
// Begins to asynchronously receive data
handler.BeginReceive(
buffer, // An array of type Byt for received data
0, // The zero-based position in the buffer
buffer.Length, // The number of bytes to receive
SocketFlags.None,// Specifies send and receive behaviors
new AsyncCallback(ReceiveCallback),//An AsyncCallback delegate
obj // Specifies infomation for receive operation
);
// Begins an asynchronous operation to accept an attempt
AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
listener.BeginAccept(aCallback, listener);
}
catch (Exception exc) { }
}
public static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Fetch a user-defined object that contains information
object[] obj = new object[2];
obj = (object[])ar.AsyncState;
// Received byte array
byte[] buffer = (byte[])obj[0];
// A Socket to handle remote host communication.
handler = (Socket)obj[1];
// Received message
string content = string.Empty;
// The number of bytes received.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
content += Encoding.Unicode.GetString(buffer, 0,
bytesRead);
// If message contains "<Client Quit>", finish receiving
if (content.IndexOf("<Client Quit>") == -1)
{
// Continues to asynchronously receive data
byte[] buffernew = new byte[1024];
obj[0] = buffernew;
obj[1] = handler;
handler.BeginReceive(buffernew, 0, buffernew.Length,
SocketFlags.None,
new AsyncCallback(ReceiveCallback), obj);
}
Console.WriteLine(content);
}
}
catch (Exception exc) { }
}
}
}
Der PHP Client:
<?php
$host = "81.20.133.51";
$port = "4510";
$timeout = 15; //timeout in seconds
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)
or die("Unable to create socket\n");
socket_set_nonblock($socket)
or die("Unable to set nonblock on socket\n");
$time = time();
while (!@socket_connect($socket, $host, $port))
{
$err = socket_last_error($socket);
if ($err == 115 || $err == 114)
{
if ((time() - $time) >= $timeout)
{
socket_close($socket);
die("Connection timed out.\n");
}
sleep(1);
continue;
}
die(socket_strerror($err) . "\n");
}
socket_set_block($this->socket)
or die("Unable to set block on socket\n");
?>
Kann jemand weiterhelfen?
Hi NewCannon,
ein guter Ansatzpunkt wäre ja, mal die Exceptions auf der .NET-Seite auszuwerten, anstatt sie einfach zu ignorieren.
Christian
Weeks of programming can save you hours of planning
Habe ich versucht aber scheinbar kommt nix an die Consolenanwendung durch
Dann schreib die Exceptions doch in das EreignisLog des Servers statt sie zu verwerfen.
Hast du mal versucht, dich mit deinem Server mit Telnet bzw. Putty zu verbinden?
Bekommst du eine Verbindung, was sagt der Debugger?
Auf welche IP-Adresse bindest du?