Error : The status callback on localhost is not a valid URL - c#

I'm trying to make an application that can send sms using twilio API
This API contains statusCallback attributes, which we can include a link that the API can send data about the delivery behavior ( if sms are received etc...)
public void sendSMS()
foreach (var toNumber in TOnumbersList)
{
var message = MessageResource.Create(
to: new PhoneNumber(toNumber),
from: new PhoneNumber(fromNumber),
body: msgBody,
provideFeedback: true,
statusCallback: new Uri("http://localhost:5000/"));// <----
}
As you can notice , in the statusCallback I precised that I would like to send the information on localhost:5000/
In my solution explorer of visual studio 2015 I added a separated project and called it windows Service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace WindowsService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
// ServiceBase.Run(ServicesToRun);
_httpListener.Prefixes.Add("http://localhost:5000/"); // add prefix "http://localhost:5000/"
_httpListener.Start(); // start server (Run application as Administrator!)
Console.WriteLine("Server started.");
Thread _responseThread = new Thread(ResponseThread);
_responseThread.Start(); // start the response thread
}
static HttpListener _httpListener = new HttpListener();
static void ResponseThread()
{
while (true)
{
HttpListenerContext context = _httpListener.GetContext(); // get a context
var a = context.Request.Url; // Now, you'll find the request URL in context.Request.Url
byte[] _responseArray = Encoding.UTF8.GetBytes("<html><head><title>Localhost server -- port 5000</title></head>" +
"<body>Welcome to the <strong>Localhost server</strong> -- <em>port 5000!</em></body></html>"); // get the bytes to response
context.Response.OutputStream.Write(_responseArray, 0, _responseArray.Length); // write bytes to the output stream
context.Response.KeepAlive = false; // set the KeepAlive bool to false
context.Response.Close(); // close the connection
Console.WriteLine("Respone given to a request.");
}
}
}
}
After that , in the configuration of the solution I precised that I wanted the service to run before the windows form project as you can notice in the picture
So once I start the solution , I went on localhost:5000 and noticed that the service is running and the page is displaying a welcoming message
But , once the sendSMS() function is called (or invoked ) ( while the service is running) I'm receiving this error :
Error : The status callback on localhost is not a valid URL
So my question is what I am doing wrong ? I would like to understand I am not very experienced with the web service techniques , did I forget to enable something? Or something related to asynchronous and synchronous issue ?
Note : In the past , (instead of using local-host ) , I have created a url using http://requestb.in/ ( which does the job of a webservice) and I have copied the created url and there was no problem sending data on the link . But with when the link is localhost , the issue is noticed

"Localhost" resolves to the machine the code is currently running on, which is 127.0.0.1 (IPv4) and ::1 (IPv6).
If you pass localhost to a remote service like Twilio, the remote service will resolve "localhost" to 127.0.0.1/::1, which is itself. This doesn't make any sense and is why Twilio rejects the URL.
The callback URL you specify must be public and reachable from Twilios services, otherwise this won't work. I usually use a cheap or free Azure website for tests like this.

Related

M2Mqtt in C# is not connected, doesn't give data

I have a project creating a websocket client side (Subscriber) to a MQTT publisher. I am quite new to C# and MQTT protocol. I follow some youtube video to make finish my very first lines connecting to this MQTT publisher to get all the train going in and out Helsinki station.
broker: "rata.digitraffic.fi"
Port: 80
Topic: trains-by-station/HKI (HKI abbr for Helsinki)
I use M2Mqtt library in dotnet to build the subscriber, somehow the client_MqttMsgPublishReceived function is never triggered. the client.IsConnected always returned false value!
You can find info of this mqtt protocol in the url below.
https://www.digitraffic.fi/rautatieliikenne/#websocket-mqtt
It gives me example in JavaScripts and it seems to run fine with the example of each MQTT. But when I tried to do it with my PC, it doesn't give me any thing, but
Hello World!!!
False
and the cmd window on hold.
SOOOO FRUSTRATING right now. it would be much appreciate if anyone can help me out.
BTW, I am using win10, I tried with dotnet 4/5/6 and m2mqtt 4.3.0.
using System.Text;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
using System;
namespace m2qttSubscriber
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!!!!");
MqttClient client = new MqttClient("rata.digitraffic.fi",
80,
false,
MqttSslProtocols.None,
null,
null);
client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
string clientID = "myclientid_" + RandomDigits(4);
client.Connect(clientID);
Console.WriteLine(client.IsConnected);
client.Subscribe(new string[] { "trains-by-station/HKI" },
new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE}) ;
}
static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
{
Console.WriteLine("SOme thing is received");
string payload = Encoding.Default.GetString(e.Message);
Console.WriteLine("Recevied {0} from", payload);
}
static public string RandomDigits(int length)
{
var random = new Random();
string s = string.Empty;
for (int i = 0; i < length; i++)
s = String.Concat(s, random.Next(10).ToString());
return s;
}
}
}
As per the comments the library used (uPLibrary.Networking.M2Mqtt) does not support MQTT over Websockets (which is what rata.digitraffic.fi:80 offers).
If you are able to use standard MQTT (over TCP/IP) then rata-mqtt.digitraffic.fi:1883 works (OP succeeded with MqttClient client = new MqttClient("rata-mqtt.digitraffic.fi", 1883, false, MqttSslProtocols.None, null, null);) and this is generally preferable to using WebSockets (there are some situations where you have to use WebSockets; e.g. code running in a browser or to bypass some filters/proxies).
Alternatively there are other libraries that do offer support for MQTT over Websockets.

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.

SignalR stays in the Connecting state when IIS doesn't respond to connect request

I'm having an issue when using SignalR and IIS on my Windows 10 machine. The problem is that IIS only allows for 10 concurrent connections. When The 10th connection is reached, the client side HubConnection will stay in the Connecting state for a long time.
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static int usedConnections = 0;
static void Main(string[] args)
{
Foo();
while (true) { }
}
static async void Foo()
{
for(int i = 0; i < 15; i++)
{
await SetupSignalR();
}
}
static async Task SetupSignalR()
{
//Set connection
var hub = new HubConnection("http://MyComputer/MyIISApp");
hub.TraceLevel = TraceLevels.All;
hub.TraceWriter = Console.Out;
//Make proxy to hub based on hub name on server
var myHub = hub.CreateHubProxy("MyIISHub");
//Start connection
hub.TransportConnectTimeout = TimeSpan.FromSeconds(5);
await hub.Start();
usedConnections++;
Console.WriteLine($"Used Conenctions: {usedConnections}");
return;
}
}
}
After a reasonable period of time I would like to display a message to the user that the HubConnection is unable to connect to the server, but I cant figure out how to either set a timeout or trigger an event. What can I do to notify the user that IIS isn't accepting the connection request?
According to your description, I suggest you could try to write the codes to monitor the connection time, if the time has exceed the 30 seconds, you could directly stop connect to the signlar server and show a error message.
Besides, the connection limit for the IIS is only happened on the windows10. If you used the windows server, there is no limit for the IIS connection.

Why is no message received in WS communication on a UWP device?

I have a WS server and I would like to broadcast messages from that server (using another web app) to all HoloLens devices that are connected to the session.
First I have implemented a MessageWebSocket client in the Hololens app that initiated a connection with a sample public WS server echo.websocket.org just to check if the setup is right on the client side. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if WINDOWS_UWP
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Web;
using System;
#endif
public class WebSocketClient : MonoBehaviour
{
void Start()
{
#if WINDOWS_UWP
int msgTime = 5;
int fadeTime = 1;
guiPhraseReporter.QueueRaport("START", msgTime, fadeTime);
MessageWebSocket ws = new MessageWebSocket();
ws.Control.MessageType = SocketMessageType.Utf8;
ws.MessageReceived += (MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) =>
{
guiPhraseReporter.QueueRaport("Trying to receive message...", msgTime, fadeTime);
try
{
using (DataReader dataReader = args.GetDataReader())
{
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
string message = dataReader.ReadString(dataReader.UnconsumedBufferLength);
Debug.Log(message);
}
}
catch (Exception ex)
{
Debug.Log("Error occurred");
}
};
ws.Closed += (IWebSocket sender, WebSocketClosedEventArgs args) => {
Debug.Log("WS closed");
};
try
{
Task connectTask = ws.ConnectAsync(new Uri("ws://echo.websocket.org")).AsTask();
connectTask.ContinueWith(async _ =>
{
string message = "Hello, World!";
using (DataWriter dataWriter = new DataWriter(ws.OutputStream))
{
dataWriter.WriteString(message);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
Debug.Log("Sending Hello World");
});
}
catch (Exception ex)
{
WebErrorStatus webErrorStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
// Add additional code here to handle exceptions.
Debug.Log(ex);
}
#endif
}
}
And it works fine, I'm able to send a message to the server, and it is echoed back and received correctly by the client.
Things however mess up when I use the actual server I'll be testing on. On my server, I have replicated the behavior from the echo.websocket.org and I echo back any message sent. I'm able to connect, the connection is not closed (Closed is never called), but I don't receive any messages.
If I test both servers using the web browser (with chrome's Smart Websocket Extension), they both work. The only difference (and only possible lead I got) is that the sample server (the one that works on Hololens) sends more headers upon connection:
vs my server:
Maybe there is some easier way to do this, but so far I didn't find any good WS wrappers that would work on UWP. Any help appreciated.
It was faulty logic on my server app after all. So there was no problem with WS communication to begin with, thank you for your time.

connecting to ServiceContract?

Continuing to learn WCF, I'm trying to write a small program that would with a click of a button take the work from texbox1 , pass it to ServiceContract and get back its length.
Here's how far I got.
Form1.cs:
...
wcfLib.Service myService = new wcfLib.Service();
private void button1_Click(object sender, EventArgs e)
{
textBox2.Text = Convert.ToString( myService.go(textBox1.Text) );
}
...
and the wcf file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace wcfLib
{
[ServiceContract]
public interface IfaceService
{
[OperationContract]
int wordLen(string word);
}
public class StockService : IfaceService
{
public int wordLen(string word)
{
return word.Length;
}
}
public class Service
{
public int go( string wordin )
{
ServiceHost serviceHost = new ServiceHost(typeof(StockService), new Uri("http://localhost:8000/wcfLib"));
serviceHost.AddServiceEndpoint(typeof(IfaceService), new BasicHttpBinding(), "");
serviceHost.Open();
int ret = **///// HOW SHOULD I PASS wordin TO StockService to get word.Length in return?**
serviceHost.Close();
return ret;
}
}
}
what I can't figure out right now, is how do I pass the wordin variable above into the ServiceContract?
You need to create the client in your form and call wordLen() directly... only a class that inherits from IfaceService can be called as a WCF service. So:
// You'll have to create references to your WCF service in the project itself...
// Right-click your form project and pick 'Add Service Reference', picking
// 'Discover', which should pick up the service from the service project... else
// enter http://localhost:8000/wcfLib and hit 'Go'.
// You'll have to enter a namespace, e.g. 'MyWcfService'... that namespace is
// used to refer to the generated client, as follows:
MyWcfService.wcfLibClient client = new MyWcfService.wcfLibClient();
private void button1_Click(object sender, EventArgs e) {
// You really shouldn't have the client as a member-level variable...
textBox2.Text = Convert.ToString(client.wordLen(textBox1.Text));
}
If your Service class is meant to host the WCF Service, it needs to be its own executable and running... put the code you have in go() in Main()
Or host your WCF Service in IIS... much easier!
Edit
IIS = Internet Information Services... basically hosting the WCF Service over the web.
To host in IIS, create a new project, "WCF Service Application". You'll get a web.config and a default interface and .svc file. Rename these, or add new items, WCF Service, to the project. You'll have to read up a bit on deploying to IIS if you go that route, but for debugging in Visual Studio, this works well.
To split into two applications, just make the form its own project... the service reference is set through the application's config file; you just point it to the address of the machine or website, e.g. http://myintranet.mycompany.com:8000/wcflib or http://myserver:8000/wcflib.
Thanks for the vote!
You've definitely got things back-to-front. You don't want to create the ServiceHost in your Go method, or at least, you'd never create it in any method invoked by the client, because how could the client call it if the service hasn't been created yet?
A service in WCF is started, and THEN you can invoke its methods from a remote client. EG, this is your Main() for the service:
ServiceHost serviceHost = new ServiceHost(typeof(StockService), new Uri("http://localhost:8000/wcfLib"));
serviceHost.AddServiceEndpoint(typeof(IfaceService), new BasicHttpBinding(), "");
serviceHost.Open();
Console.WriteLine("Press return to terminate the service");
Console.ReadLine();
serviceHost.Close();
Then for your client you'd use "Add Service Reference" in Visual Studio (right-click on the Project in Solution Explorer to find this menu option) and enter the address for the service. Visual Studio will create a proxy for your service, and this is what you'd instantiate and use on the client. EG:
MyServiceClient client = new MyServiceClient();
textBox2.Text = Convert.ToString( client.wordLen(textBox1.Text) );

Categories