Embedded Nancy not listening - c#

I read a couple of related questions which had an issue with accessing nency from a remote computer. However, I am unable to access nancy from my own pc.
Here is my code:
class Program
{
static void Main(string[] args)
{
HostConfiguration hostConfigs = new HostConfiguration();
//hostConfigs.RewriteLocalhost = true;
hostConfigs.UrlReservations.CreateAutomatically = true;
using (var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234")))
{
host.Start();
Console.WriteLine("Running on http://+:1234");
Console.WriteLine(host.ToString());
}
Console.ReadKey();
}
}
public class HelloModule : NancyModule
{
public HelloModule()
{
Get["/"] = parameters => Response.AsJson("Success");
Get["/nancy"] = parameters => Response.AsJson("Success");
}
}
}
I am administrator on my PC and I do not get any exception. If I type http://localhost:1234 or http://127.0.0.1:1234 to my browser (with /nancy and without) I would expect a response. However, I do net get any reponse. Further, in the list produced with netstat -ano I do not see any process listing on port 1234. I downloaded the latest version of nancy via nuget.
Do you have any idea?

The following line should work as expected:
var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234"))
But what happens with a using statement, is that anything specified between ( and ) (simply put) is disposed after the closing brace (}) of the same using statement. So what is actually happening is, the host gets created, is started, and is disposed right after it printed some lines to the console.
Simply put, move the ReadKey call inside the using statement. There it will wait until a key is pressed, and the host will be disposed after that event has occurred.

Related

Application sees zero/different tables from what local DynamoDB instance has

I'm building a WebAPI project. I have DynamoDB downloaded and running locally with -inMemory. After creating a couple of tables, I run this command locally: aws dynamodb list-tables --endpoint-url http://localhost:8000, which results in:
{
"TableNames": [
"Users",
"Tmp"
]
}
When I run my application, I create a client, and query for tables:
using (var client = DatabaseClientFactory.CreateClient())
{
// debugging
var temp = await client.ListTablesAsync();
return $"{temp.TableNames.Count} tables: " + string.Join(", ", temp.TableNames);
}
This returns 0 tables:
The DB client is a lightly-modified version of this starter code:
using System;
using System.Net;
using System.Net.NetworkInformation;
using Amazon;
using Amazon.DynamoDBv2;
namespace Database
{
// Adapted from https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.NET.01.html
public static class DatabaseClientFactory
{
/*-----------------------------------------------------------------------------------
* If you are creating a client for the Amazon DynamoDB service, make sure your credentials
* are set up first, as explained in:
* https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SettingUp.DynamoWebService.html,
*
* If you are creating a client for DynamoDBLocal (for testing purposes),
* DynamoDB-Local should be started first. For most simple testing, you can keep
* data in memory only, without writing anything to disk. To do this, use the
* following command line:
*
* java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -inMemory
*
* For information about DynamoDBLocal, see:
* https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html.
*-----------------------------------------------------------------------------------*/
private const int Port = 8000;
public static AmazonDynamoDBClient CreateClient()
{
// If this line throws, you need to download the AWS CLI, run `aws configure` and specify your access key.
var client = new AmazonDynamoDBClient();
var dynamoDbConfig = new AmazonDynamoDBConfig();
// First, check to see whether anyone is listening on the DynamoDB local port
// (by default, this is port 8000, so if you are using a different port, modify this accordingly)
var portAvailable = IsPortAvailable();
if (portAvailable)
{
Console.WriteLine(" -- The local instance of DynamoDB is NOT running. Using PROD.");
// TODO: this should come out of appSettings.Production.json
dynamoDbConfig.RegionEndpoint = RegionEndpoint.USEast2;
}
else
{
// Local address ignores AWS credentials
Console.WriteLine(" -- The local instance of DynamoDB is running!");
dynamoDbConfig.ServiceURL = $"http://localhost:{Port}";
}
client = new AmazonDynamoDBClient(dynamoDbConfig);
return client;
}
private static bool IsPortAvailable()
{
// Evaluate current system TCP connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
foreach (IPEndPoint endpoint in tcpConnInfoArray)
{
if (endpoint.Port == Port)
{
return false;
}
}
return true;
}
}
}
That's odd - my two tables don't appear.
Even more strange: if I make calls like client.CreateTableAsync, they successfully create a table, and the return value of my API call becomes 1 tables: CREATED_IN_CODE
It seems like I have two versions of DynamoDB running locally on the same port - one the application accesses, and one that the CLI accesses.
Why is my app seeing a wrong/different list of tables?
Some other things I tried to no avail:
Nuking/reinstalling DynamoDB
Restarting my PC
Reverting to a previous version of my code from earlier today
Looking for the CREATED_IN_CODE table in AWS in different regions
The above code worked fine for me. Sometimes you need to be sure there is a region set, even though you are setting a ServiceUrl.

Wireguard tunnel source to c#.Net: Service Run troubleshooting

I'm trying to make a simple console app client (starter.exe) on c# .NET Framework 4.6 to make a WireGuard protocol based connection using Wireguard source code.
What is done:
Downloaded wireguard source code from here: git://git.zx2c4.com/wireguard-windows
Successfuly built Tunnel.dll in ..\embeddable-dll-service\amd64\tunnel.dll via build.bat
Created a project in Visual Studio 2015.using the c# code from ..\embeddable-dll-service\csharp
Starting from here some strange thing are happenning:
if launching starter.exe \service <path to *.conf> I receive the
error
Service run error: The service process could not connect to the
service controller.
if launching starter.exe without parameters everything works fine until I remove the if{} block:
Unhandled Exception: System.ComponentModel.Win32Exception: The service
did not respond to the start or control request in a timely fashion
at WireGuardTunnel.Service.Add(String configFile) in
D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Service.cs:line
69 at WireGuardTunnel.Program.Main(String[] args) in
D:\Depository\BitBucket\WireGuard_Tunnel_Repository\WireGuardTunnel_proj\Launcher\Program.cs:line
83
That means even if the code in if{} block is not executed it influencese somehow the application behaviour.
Next, as I want to make my app work with parameters I solved the
issue by removing return afer Service.Run and passing args[1] to Service.Add(args[1]). It works OK, but I have an extra log line (the first one due to Service.Run perpetual error described above) in the log:
Service run error: The service process could not connect to the
service controller. 235660: [TUN] [chicago4] Watching network
interfaces 245661: [TUN] [chicago4] Resolving DNS names
245661: [TUN] [chicago4] Creating Wintun interface 225660: [TUN]
[chicago4] Starting WireGuard/0.3.1 (Windows 6.1.7601; amd64)
So finally the questions:
Why Service.Run(confFile) does not work
Why Service.Run(confFile) influences the Service.Add(confFile)
Why if{} block is executed when I launch starte.exe with no parameters
The original Program.cs without modification:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;
namespace Tunnel
{
class Program
{
[DllImport("kernel32.dll")]
private static extern bool SetConsoleCtrlHandler(SetConsoleCtrlEventHandler handler, bool add);
private delegate bool SetConsoleCtrlEventHandler(UInt32 signal);
public static void Main(string[] args)
{
string baseDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
string configFile = Path.Combine(baseDirectory, "demobox.conf");
string logFile = Path.Combine(baseDirectory, "log.bin");
if (args.Length == 2 && args[0] == "/service")
{
configFile = args[1];
Service.Run(configFile);
return;
}
try { File.Delete(logFile); } catch { }
Ringlogger log = new Ringlogger(logFile, "GUI");
var logPrintingThread = new Thread(() =>
{
var cursor = Ringlogger.CursorAll;
while (Thread.CurrentThread.IsAlive)
{
var lines = log.FollowFromCursor(ref cursor);
foreach (var line in lines)
Console.WriteLine(line);
Thread.Sleep(300);
}
});
logPrintingThread.Start();
SetConsoleCtrlHandler(delegate
{
Service.Remove(configFile);
Environment.Exit(0);
return true;
}, true);
try
{
Service.Add(configFile);
logPrintingThread.Join();
}
finally
{
Service.Remove(configFile);
}
}
}
}
Bit late to the party but I was having the exact same issue as above and discovered that in order to get everything working correctly you have to have Tunnel.Service.Run("path to config") defined on application initialization either in your main loop or your constructor then you can run Tunnel.Service.Add("path to config", true) which will create the service and start the VPN connection. It's also good practice to destroy the service on close using Tunnel.Service.Remove("path to config", true) as the service will continue to run and you will still be connected to your VPN until it is stopped manually.

How to keep common name of SSL while changing port wss

I have a problem here. I created a windows app that requires interaction between browser and desktop apps. In the desktop app, I include WebSocket Secure made by [Dave](WebSocket Server in C#).
I have a valid pfx file. While using the default port (443), everything runs smoothly. The URL shows the CN of the SSL. My window app then has to use other port other than default ones (443), when I change in setting it runs not as per CN of the SSL but instead localhost:portnum. how to make it run using CN in ports other than 443? Please help.
I will try to answer this.
I have checked the link that you have pasted and came across the following code snippet:
private static void Main(string[] args){
IWebSocketLogger logger = new WebSocketLogger();
try
{
string webRoot = Settings.Default.WebRoot;
int port = Settings.Default.Port;
// used to decide what to do with incoming connections
ServiceFactory serviceFactory = new ServiceFactory(webRoot, logger);
using (WebServer server = new WebServer(serviceFactory, logger))
{
server.Listen(port);
Thread clientThread = new Thread(new ParameterizedThreadStart(TestClient));
clientThread.IsBackground = false;
clientThread.Start(logger);
Console.ReadKey();
}
}
catch (Exception ex)
{
logger.Error(null, ex);
Console.ReadKey();
}
}
Within the try block there is this code line:
int port = Settings.Default.Port;
Maybe trying setting that to an auto assign port fix your problem.

MapReduce.SDK: How to wait for MapReduce job?

I'm using the Microsoft MapReduce SDK to start a Mapper only job.
The call to hadoop.MapReduceJob.ExecuteJob is throwing a "Response status code does not indicate success: 404 (not found)" exception immediately.
When inspecting the HDInsight Query Console the job successfully starts and finishes later. It also writes proper output files.
My guess is, ExecuteJob is trying to access output data before the job has finished.
What is the correct way to handle this situation?
using System;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using Microsoft.WindowsAzure.Management.HDInsight;
using Microsoft.Hadoop.MapReduce;
using AzureAnalyzer.MultiAnalyzer;
namespace AzureAnalyzer
{
class Program
{
static void Main(string[] args)
{
IHadoop hadoop = Hadoop.Connect(Constants.azureClusterUri, Constants.clusterUser,
Constants.hadoopUser, Constants.clusterPassword, Constants.storageAccount,
Constants.storageAccountKey, Constants.container, true);
try {
var output = hadoop.MapReduceJob.ExecuteJob<MultiAnalyzerJob>();
}
catch (Exception ex)
{
Console.WriteLine("\nException: " + ex.Message);
}
}
}
}
I got another way to do the same thing but takes a bit of effort since it requires the mapper and reducer files to be transferred to the hadoop cluster storage.
you need to add Microsoft.Hadoop.Client then Microsoft Azure HDInsight NuGet package as well.
var jobcred = new BasicAuthCredential();
jobcred.UserName = "clusteruserid";
jobcred.Password = "clusterpassword";
jobcred.Server = new Uri("https://clusterurl");
StreamingMapReduceJobCreateParameters jobpara = new StreamingMapReduceJobCreateParameters()
{
JobName="mapreduce",
Mapper = "Mapper.exe",
Reducer = "Reducer.exe",
Input= "wasb:///mydata/input",
Output = "wasb:///mydata/Output",
StatusFolder= "wasb:///mydata/sOutput"
};
jobpara.Files.Add("wasb:///mydata/Mapper.exe");
jobpara.Files.Add("wasb:///mydata/Reducer.exe");
// Create a Hadoop client to connect to HDInsight.
var jobClient = JobSubmissionClientFactory.Connect(jobcred);
// Run the MapReduce job.
JobCreationResults mrJobResults = jobClient.CreateStreamingJob(jobpara);
// Wait for the job to complete.
Console.Write("Job running...");
JobDetails jobInProgress = jobClient.GetJob(mrJobResults.JobId);
while (jobInProgress.StatusCode != JobStatusCode.Completed
&& jobInProgress.StatusCode != JobStatusCode.Failed)
{
Console.Write(".");
jobInProgress = jobClient.GetJob(jobInProgress.JobId);
Thread.Sleep(TimeSpan.FromSeconds(10));
}
// Job is complete.
Console.WriteLine("!");
Console.WriteLine("Job complete!");
Console.WriteLine("Press a key to end.");
Console.Read();
Hope this helps. I was able to run jobs without throwing any exceptions.
this in fact waits for the job to be complete.
Please verify if all required services to run the program are up and running. The 404 error indicates that some URL the program tries to access internally is not accessible.

Clickonce application and file handler behavior

I have a clickonce application, and I have set up several file handlers for this application (for the sake of this example, I want to handle files with either the .aaa or .bbb extensions).
If I select a single file with one of these extensions, my application starts up as expected, everything is good. But if I select multiple files and open them (either by hitting Enter or by right clicking and selecting Open), then multiple instances of my aopplication are started up - one instance per file that was selected.
This is not the behavior I expected, I want just one instance to start with multiple file entries in the AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData. Can this be achieved, or is my expectation incorrect?
Edit:
Just to elaborate: we have followed the single instance approach as mentioned by #Matthias, the first instance to start up creates a named server pipe. Subsequent instances then start up, detect that they are secondary, communicate their command line arguments (filename) through to the main instance via the named pipe, then quit. The main instance receives the filename via the named pipe, and does its thing (starts up a file import wizard).
The issue comes when a user selects several files (i.e. 5 files), then selects to open those files in the application. Instead of getting one secondary instance starting with 5 file names supplied on the command line, I'm getting 5 secondary instances of the application starting, each with a single filename on the command line. Each of these then creates a client named pipe and communicates that filename to the main instance - so the server named pipe receives 5 separate messages.
Follow up thoughts:
after chatting about this it occurs to me that maybe this is just the way registered file handlers work, maybe it is not related to clickonce. Maybe the solution is for the server named pipe to pause after receiving each message and to attempt to queue messages before actioning them?
You can achieve this by implementing a single instance application. If the application is already running (second call), you can use named pipes to inform the application (first call) of a file open event.
EDIT
Found a code snippet from an earlier project. I want to underline that the code definitely needs improvements, but it should be a good point where you can start from.
In your static main:
const string pipeName = "auDeo.Server";
var ownCmd = string.Join(" ", args);
try
{
using (var ipc = new IPC(pipeName))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new ServerForm();
ipc.MessageReceived += m =>
{
var remoteCmd = Encoding.UTF8.GetString(m);
form.Invoke(remoteCmd);
};
if (!string.IsNullOrEmpty(ownCmd))
form.Invoke(ownCmd);
Application.Run(form);
}
}
catch (Exception)
{
//MessageBox.Show(e.ToString());
if (string.IsNullOrEmpty(ownCmd))
return;
var msg = Encoding.UTF8.GetBytes(ownCmd);
IPC.SendMessage(pipeName, msg);
}
The IPC class:
public class IPC : IDisposable
{
public IPC(string pipeName)
{
Stream = new NamedPipeServerStream(pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
AsyncCallback callback = null;
callback = delegate(IAsyncResult ar)
{
try
{
Stream.EndWaitForConnection(ar);
}
catch (ObjectDisposedException)
{
return;
}
var buffer = new byte[2000];
var length = Stream.Read(buffer, 0, buffer.Length);
var message = new byte[length];
Array.Copy(buffer, message, length);
if (MessageReceived != null)
MessageReceived(message);
Stream.Disconnect();
// ReSharper disable AccessToModifiedClosure
Stream.BeginWaitForConnection(callback, null);
// ReSharper restore AccessToModifiedClosure
};
Stream.BeginWaitForConnection(callback, null);
}
private NamedPipeServerStream Stream
{
get;
set;
}
#region IDisposable Members
public void Dispose()
{
if (Stream != null)
Stream.Dispose();
}
#endregion
public static void SendMessage(string pipeName, byte[] message)
{
using (var client = new NamedPipeClientStream(".", pipeName))
{
client.Connect();
client.Write(message, 0, message.Length);
client.Close();
}
}
~IPC()
{
Dispose();
}
public event MessageHandler MessageReceived;
}
The answer to the problem was to have a small delay at the server end of the pipe. In summary:
the first started instance of the app is the owner of the server end of the pipe, subsequent instances of the app are a client
When receiving a message from a client, a timer was started, if the timer was already started then it was reset. The passed file name is added to a list.
The timer delay was set to 2 seconds, once the tick event occurred (so it had been 2 seconds since the last client communication) the single instance server would take the appropriate action with the list of file names
This is not the behavior I expected, I want just one instance to start with multiple file entries in the AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData. Can this be achieved, or is my expectation incorrect?
My expectation was incorrect - you can only pass through a single file name to a registered file handler, each file name starts a separate instance of the handler.

Categories