Task hang infinitely when calling .Wait() in kafka-net - c#

I'm currently trying to post messages from a for-loop on a kafka server running on my local machine using the kafka-net library in c# (https://github.com/Jroland/kafka-net), following the example given on the linked repo, my code is the following.
string kafkaServer = "http://" + ip + ":" + port;
Uri uri = new Uri(kafkaServer);
var options = new KafkaOptions(uri);
var router = new BrokerRouter(options);
var client = new Producer(router);
...
foreach(string sumup in LS){
payloadJson["fullPathDataFolder"] = remoteFolder;
payloadJson["globalName"] = GloablName;
payloadJson["name"] = name;
payloadJson["text"] = sumUp + "\n";
payloadJson["type"] = type;
string payload = payloadJson.ToString();
KafkaNet.Protocol.Message msg = new KafkaNet.Protocol.Message(payload);
client.SendMessageAsync(topic, new List<KafkaNet.Protocol.Message> { msg }).Wait();
}
This code run through the first iteration and i'm able to retrieve the first string from a second machine linked to the same server with a consumer.
Then the code here above remain stuck at the intruction:
client.SendMessageAsync(topic, new List<KafkaNet.Protocol.Message> { msg }).Wait();
If now I remove the .Wait() this code run quite fast but it randomly ignore some of the string i send
What am I missing ?
P.S.
I'v tried also to use Confluent.kafka and i got similar problems
P.P.S.
It's important that this program run sequentially.

Related

Xamarin.Android TcpClient not working sometimes

I'm trying to create an application where I have to use WHOIS to get some information I need.
To get the WHOIS information I use this function I found on here and adjusted a little:
string Whois(string domain, string whoisServer = "whois.iana.org")
{
string toReturn = "";
TcpClient tcpClinetWhois = new TcpClient(whoisServer, 43);
MemoryStream memoryStreamWhois = new MemoryStream();
Task copying = tcpClinetWhois.GetStream().CopyToAsync(memoryStreamWhois);
StreamWriter streamWriter = new StreamWriter(tcpClinetWhois.GetStream());
streamWriter.WriteLine(domain);
streamWriter.Flush();
copying.Wait(3000);
toReturn = Encoding.ASCII.GetString(memoryStreamWhois.ToArray());
if (toReturn.Contains("refer:"))
{
toReturn = Whois(domain, toReturn.Split('\n').Where(W => W.StartsWith("refer:")).Select(R => R.Replace("refer:", "").Trim()).First());
}
return toReturn;
}
When I run it, it works for most TLDs like .com or .org but not for .co.uk or .network and probably others too. I have no idea why it wouldn't work because the right WHOIS server gets selected for the TLD. I am also not getting any errors.
I'm using .Net7.0 and my Android 11 phone for testing.
I've tested this exact same function with the exact same domains on the same network but in a Console Application with no problems at all! Everything works fine except when I try this function in a Xamarin Application.

c# Using static variables in different projects

I have a solution with two projects which act as Server and Client respectively. The Client is a simple console application which sends data to the server. The server is a WPF application which receives the data and displays it in a datagrid. The MVVM approach is used here.
In the Server UI there are three textboxes in which the user can type in:
IP Address: ("127.0.0.1")
Port: (some port)
Delimeter: (some char like '#' for example)
The challenge for me in this one is that, whatever delimeter the user provides, it should be used in the client project, to be put in between the data which is to be sent. For example the client sends:
Name + Delimeter + Surname + Delimeter + Age
What i have tried:
I added a Utils class with static fields for IPAddress, port and delimeter like this:
public class Utils
{
public static string IP_ADDRESS = " ";
public static int PORT = 0;
public static char DELIMETER = '\0';
}
I then tried to change these values in my ViewModel where the respective properties which are bound to the UI are by assigning them:
private void storeData()
{
Utils.IP_ADDRESS = IP;
Utils.PORT = Port;
Utils.DELIMETER = Delimeter;
}
In the client program:
static void Main(string[] args)
{
Client client = new Client(Utils.IP_ADDRESS, Utils.PORT);
while (true)
{
client.SendData("some Name" + Utils.DELIMETER + "some Surname" + Utils.DELIMETER + some Age + Utils.DELIMETER + "something else");
Thread.Sleep(3000);
}
}
The problem here is that whenever i start a new Client instance the values from the util class are still the default ones (null).
Any help is appreciated.
Let's break down your problem:
The server can change ip or ports at will and the clients will somehow guess the new port and connect.
The server changes the delimiter at will and the clients adapt to the new delimiter.
Problem 1 is impossible. Information cannot magically get transferred to clients before the client connects to the server, and the client needs ip and ports to connect to the server. Whatever technique you use to transfer the ip and port to the client is a better communication channel than your client/server, so you don't need a client/server.
Problem 2 has been solved by WCF already. Use WCF and SOAP or REST (which is just HTML).
Here is a sample of what the code would look like for the clients to determine the delimiter before sending the main request:
class Server
{
private TcpListener _listener = new TcpListener(12312);
public void Start()
{
_listener.Start();
while (true)
{
var client = _listener.AcceptTcpClient();
var stream = client.GetStream();
var request = getRequest(stream);
if (request == "GetDelimiter")
{
SendResponse(Utils.DELIMITER, stream);
}
else
{
ProcessNameSurnameAge(request);
}
}
}
}
class Client
{
private TcpClient _client = new TcpClient();
public void DoTheThing()
{
_client.Connect("127.0.0.1", 12312);
var stream = _client.GetStream();
SendRequest("GetDelimiter", stream);
var delimiter = GetResponse(stream);
var newRequest = "some Name" + delimiter + "some Surname" + delimiter + "some Age" + delimiter + "something else";
SendRequest(newRequest);
}
}
Note that I skip over the encoding details of sending data over TCP because it seems like you've already got a handle on that.
I was able to solve this in a rather simple manner. Steps i used to solve are as follow:
In the server:
Created a text file in my solution.
When the server starts in my view model, i saved the properties ip, port and delimeter in a string array.
Next i used the IO File class to write the content of the array in the text file.
In the client:
First i read from the file.
Next i created the client instance and passed the ip and port as parameters to it's constructor.
Thank you D Stanley and Damian Galletini for your suggestions. Also thank you everybody else who tried to help.

CoolUtils TotalPDFPrinterX causes ASP C# site to crash

My company has purchased the CoolUtils TotalPDFPrinterX from https://www.coolutils.com/TotalPDFPrinterX
I make an HTTP PUT from Postman to the API and I get “Could not get any response”.
When running on my Windows machine the PDF prints fine however on the server the site crashes and in the event log I get the error "A process serving application pool '[MY_APP_POOL]' failed to respond to a ping. The process id was '[MY_PROCESS_ID]'."
Here is my C# code:
PDFPrinterX ppx = new PDFPrinterX();
ppx.Print(fileName, printerName, "-ap Default");
if (ppx.ErrorMessage != null)
{
WriteToSQL(id, false, ppx.ErrorMessage, 2);
Console.WriteLine(ppx.ErrorMessage);
}
By writing to the event log I know the site crashes on this line: PDFPrinterX ppx = new PDFPrinterX(); I have also surrounded the above code with a try catch and no exception is thrown. The site still crashes.
Things I have tried:
Uninstalling and Reinstalling the CoolUtils software
Giving EVERYONE Full control to the site folder and the CoolUtils program folder
Creating a C# desktop application using the same code. THIS WORKS FINE ON THE SERVER. It's just the ASP site that crashes.
Does anyone know what might be causing this?
The more I research this thing online the more I'm inclined to say that ActiveX which is the X in PDFPrinterX doesn't seem to work well when hosted in IIS.
I've seen a few forums where they say it works fine when they debug on localhost but when deployed to server is crashes.
...works fine when used inside localhost(Visual studio)
One of their feature pages shows that it requires Win 2000/NT/XP/2003/Vista/7
You should look into whether your server supports ActiveX components that can work in conjunction with IIS.
Looking at one of their other products support page: TotalPDFConverterX:
the following note in my opinion may also apply to TotalPDFPrinterX, given its dependency on ActiveX as well.
Note: Pay attention to some details during installation Total PDF Converter X:
Do not forget to register ActiveX in your web-server account.
Total PDF Converter X supports only Internet Explorer, Mozilla and Firefox browsers.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Thanks to #Nkosi I was able to find a workaround.
ActiveX works only with 32-bit internet information server. 64-bit server is not supported. Use command line version instead.
Our IIS server is 64 bit so that is what probably caused the site to hang up.
Buttt... the command line still worked in printing the PDFs on the server.
Client side code (makes the HTTP POST):
private void SendToPrinter(string fileName, string printerName, int id, decimal documentSequence)
{
// use http client to make a POST to the print api
using (var client = new HttpClient())
{
// compile the values string to transfer in POST
// should finish to look something like this:
// C:\print.pdf&PRTFTW_OFIT&ValShip-155320-1
var values = new Dictionary<string, string>
{
{ "", fileName + "&" + printerName + "&ValShip-" + id + "-" + documentSequence},
};
// URL encode the values string
var content = new FormUrlEncodedContent(values);
// make the POST
// DEBUG
var response = client.PostAsync("http://localhost:54339/api/print", content);
// retrieve the response
var responseString = response.Result.ToString();
}
}
Server side code (receives the HTTP POST):
using System;
using System.Net.Http;
using System.Web;
using System.Web.Http;
namespace api.valbruna.print.Controllers
{
public class PrintController : ApiController
{
// POST api/print
public HttpResponseMessage Post(HttpRequestMessage request)
{
try
{
// parse the content recieved from the client
var content = request.Content.ReadAsStringAsync().Result;
// decode the content, certain characters such as
// '&' get encoded to URL lingo such as '%26'
content = HttpUtility.UrlDecode(content);
// split the string into 3 seperate parts
String[] str = content.Split('&');
// remove the equal sign from the first string
str[0] = str[0].Trim('=');
// compile the arguments command line string
// should finish to look something like this:
// "C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe" "C:\print.pdf" -p"\\PRINTERS\PRTFTW_OFIT" -ap Default -log "C:\inetpub\logs\CoolUtils\log-ValShip-155320-4.txt" -verbosity detail"
String arguments = "\"" + str[0] + "\" -p\"\\\\PRINTERS\\" + str[1] +
"\" -ap Default -log \"C:\\inetpub\\logs\\CoolUtils\\log-" + str[2] +
".txt\" -verbosity detail";
// file location for PDFPrinterX.exe
String file = #"C:\Program Files (x86)\CoolUtils\Total PDF PrinterX\PDFPrinterX.exe";
// start the process
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
startInfo.FileName = file;
startInfo.Arguments = arguments;
process.StartInfo = startInfo;
process.Start();
return new HttpResponseMessage() { Content = new StringContent(content) };
}
catch (Exception e)
{
return new HttpResponseMessage() { Content = new StringContent(e.Message) };
}
}
}
}

SSDP Search in Windows Phone 8

I'm new at SSDP/UPNP/Sockets and all that jazz. I'm playing around with it a bit and I just want to see what a generic SSDP search on my network will bring up.
Using this SSDP Sniffer app, I get a lot of results so I'm attempting to recreate this.
I'm using the following code, which I've found various versions of, but all the tweaking I do doesn't appear to bring back any results. I pretty much at a loss here and would appreciate any guidance.
thanks!
private const string SSDP_IP = "239.255.255.250";
private const string SSDP_PORT = "1900";
private const string SSDP_QUERY = "M-SEARCH * HTTP/1.1\r\n" +
"Host: " + SSDP_IP + ":" + SSDP_PORT + "\r\n" +
"Man: ssdp:discover\r\n" +
"ST: ssdp:all\r\n";
DataGramSocket socket;
async public void SsdpQueryAsync()
{
var remoteIP = new Windows.Networking.HostName(SSDP_IP);
var reqBuff = Encoding.UTF8.GetBytes(SSDP_QUERY);
socket = new DatagramSocket();
socket.MessageReceived += (sender, args) =>
{
// This is invoked for each device that responds to the query...
Task.Run(() =>
{
// do something useful
});
};
await socket.BindEndpointAsync(null, "");
socket.JoinMulticastGroup(remoteIP);
using (var stream = await socket.GetOutputStreamAsync(remoteIP, SSDP_PORT))
{
await stream.WriteAsync(reqBuff.AsBuffer());
}
await Task.Delay(5000);
}
I'm not familiar with C# or dotnet APIs, but I can see some details wrong with the M-SEARCH message:
MAN header must be enclosed in double quotes, so MAN: "ssdp:discover"\r\n
MX header is missing (required for multicast)
USER-AGENT header is missing
missing an empty line in the end
Header names are supposedly case insensitive, but I'd use upper case just in case...
See the Device Architecture reference pdf for more details

WebSockets in firefox

For implementing my websocket server in C# I'm using Alchemy framework. I'm stuck with this issue. In the method OnReceive when I try to deserialize json object, I get a FormatException:
"Incorrect format of the input string." (maybe it's different in english, but I'm getting a localized exception message and that's my translation :P). What is odd about this is that when I print out the context.DataFrame I get: 111872281.1341000479.1335108793.1335108793.1335108793.1; __ad which is a substring of the cookies sent by the browser: __gutp=entrystamp%3D1288455757%7Csid%3D65a51a83cbf86945d0fd994e15eb94f9%7Cstamp%3D1288456520%7Contime%3D155; __utma=111872281.1341000479.1335108793.1335108793.1335108793.1; __adtaily_ui=cupIiq90q9.
JS code:
// I'm really not doing anything more than this
var ws = new WebSocket("ws://localhost:8080");
C# code:
static void Main(string[] args) {
int port = 8080;
WebSocketServer wsServer = new WebSocketServer(port, IPAddress.Any) {
OnReceive = OnReceive,
OnSend = OnSend,
OnConnect = OnConnect,
OnConnected = OnConnected,
OnDisconnect = OnDisconnect,
TimeOut = new TimeSpan(0, 5, 0)
};
wsServer.Start();
Console.WriteLine("Server started listening on port: " + port + "...");
string command = string.Empty;
while (command != "exit") {
command = Console.ReadLine();
}
Console.WriteLine("Server stopped listening on port: " + port + "...");
wsServer.Stop();
Console.WriteLine("Server exits...");
}
public static void OnReceive(UserContext context) {
string json = "";
dynamic obj;
try {
json = context.DataFrame.ToString();
Console.WriteLine(json);
obj = JsonConvert.DeserializeObject(json);
} catch (Exception e) {
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return;
}
}
On the C# side I'm using Newtonsoft.Json, though it's not a problem with this library...
EDIT:
One more thing - I browsed through the code in here: https://github.com/Olivine-Labs/Alchemy-Websockets-Example and found nothing - I mean, I'm doing everything the same way authors did in this tutorial...
EDIT:
I was testing the above code in Firefox v 17.0.1, and it didn't work, so I tested it under google chrome, and it works. So let me rephrase the question - what changes can be made in js, so that firefox would not send aforementioned string?
I ran into the same issue - simply replacing
var ws = new WebSocket("ws://localhost:8080");
with
var ws = new WebSocket("ws://127.0.0.1:8080");
fixed the issue for me.
In C# console app I connect the client to the server using :
var aClient = new WebSocketClient(#"ws://127.0.0.1:81/beef");
Your code above is connecting using
var ws = new WebSocket("ws://localhost:8080");
There could be one of two issues -
First is to see if WebSocketClient works instead.
To make sure your url is of the format ws://ur:port/context. This threw me off for a while.

Categories

Resources