HttpListener Problem - c#

I have to establish an HttpListener that will wait for requests made by our client's server. I have to receive that request on port 8088 and extract the query string. That is the easy part.
I'm running the HttpListener in a windows service. I cannot get it to fire properly. I build the setup project install the service on our server and it never starts. I suspect there's an error with my code.
HttpListenerClass:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
namespace lalalolo
{
class HttpListenerClass
{
bool keepAlive = true;
public void AddToFile(string contents)
{
var fs = new FileStream(#"C:\HttpListenerserv.txt", FileMode.OpenOrCreate, FileAccess.Write);
var sw = new StreamWriter(fs);
sw.BaseStream.Seek(0, SeekOrigin.End);
sw.WriteLine(contents);
sw.Flush();
sw.Close();
}
private HttpListener listener;
public HttpListenerClass()
{
ThreadPool.SetMaxThreads(50, 100);
ThreadPool.SetMinThreads(50, 50);
listener = new HttpListener();
listener.Prefixes.Add("http://*:8088/");
}
public void Start()
{
listener.Start();
if(keepalive == true){
{
try
{
HttpListenerContext ctx = listener.GetContext();
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessRequest), ctx);
}
catch(Exception ex)
{
AddToFile(ex.Message);
}
}
}
}
public void Stop()
{
listener.Stop();
keepalive == false;
}
public void ProcessRequest(object listenerContext)
{
try
{
var context = (HttpListenerContext)listenerContext;
string QS = context.Request.QueryString["ID"];
AddToFile(QS);
}
catch(Exception ex)
{
AddToFile(ex.Message);
}
}
}
}
Service1.cs:
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading;
namespace lalalolo
{
public partial class HttpListenerTest1 : ServiceBase
{
HttpListenerClass HTTP = new HttpListenerClass();
public void AddToFile(string contents)
{
var fs = new FileStream(#"C:\HttpListenerserv.txt", FileMode.OpenOrCreate, FileAccess.Write);
var sw = new StreamWriter(fs);
sw.BaseStream.Seek(0, SeekOrigin.End);
sw.WriteLine(contents);
sw.Flush();
sw.Close();
}
public HttpListenerTest1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
HTTP.Start();
}
protected override void OnStop()
{
HTTP.Stop();
}
}
}
What am I doing wrong?
Thank you guys!

Queuing worker items in a while(true) loop? Are you serious?!
Your OnStart method never returns because of that while loop. However, returning from the OnStart method is essential for the service manager to know, that your service started correctly.
Your service will probably just die with an OutOfMemoryException or something similar, because of that endless loop.
Suggestion:
Try adopting this sample. It is in IronPython but that also uses the .NET framework. Hint: The while(true) in that implementation should be changed to be able to break the while loop when your service is being stopped. Additionally, you must call serveforever in your Start method in an async way.
This should get you going.

Related

SignalR client consumes all ports on the machine

We are seeing a very strange issue with our signalR client that results in complete port exhaustion on the machine running the code. Over 16000 ports end up in the Close_Wait state.
The logs show that the Closed handle is firing several hundred times a second.
The program can run fine for hours or days before the issue occurs.
How is it possible to make the Closed handle in the code below fire continuously until all ports are exhausted?
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApp
{
public class TestEvents
{
private HubConnection _connection;
private IHubProxy<ITestHub, ITestClientContract> Proxy;
public TestEvents()
{
string url = "http://myserver/MySignalRHub";
_connection = new HubConnection(url);
_connection.Closed += HubConnectionOnClosed;
_connection.Reconnected += HubConnectionOnReconnected;
_connection.Reconnecting += HubConnectionOnReconnecting;
Proxy = _connection.CreateHubProxy<ITestHub, ITestClientContract>("TestHub");
}
public async Task Start()
{
await _connection.Start();
var result = await Proxy.CallAsync(h => h.TestMethod("test"));
Console.WriteLine($"Got {result} from connection {_connection.ConnectionId}");
}
private async void HubConnectionOnClosed()
{
Console.WriteLine("Closed");
try
{
await _connection.Start();
}
catch(Exception ex)
{
Console.WriteLine("Error");
}
}
private async void HubConnectionOnReconnected()
{
Console.WriteLine("Reconnected");
}
private async void HubConnectionOnReconnecting()
{
Console.WriteLine("Reconnecting");
}
}
}

Multithreaded network application issues

I've looked at least a hundred threads and none gave me a solution to my specific problem so far and i got tired of looking,
I'm trying to emulate a runescape game server in C#,
I need to receive lots of connections and parse the requests and send out responses for them until the game has loaded all the files, and then proceed to the actual login protocol. this needs to be able to handle multiple connections per second, as in, i handle 3 basic protocols "jaggrab", "ondemand" and then regular game protocol i.e; login, player updating etc these are all handled on the same port
My Server class listens for connections on one thread, while on another thread my PipelineFactory handles the connections in a Queue one by one as fast as it can, meanwhile there is a TaskPool thread which is executing PoolableTask objects at their own individual intervals... this works fine except as soon as I accept a connection both the pool and server threads begin to block and furthermore, the server object stops listening for connections all together but the thread seems to keep running.. I assume this is because the TcpListener.Pending() is not being updated? but i cant seem to find a function to update this list in the docs or anywhere
I seem to be using the threads the way all the multithreading tutorials explain them to work? i dont really understand what im doing wrong.. heres the important parts of my code:
MainEntry.cs:
using System;
using System.Threading;
using gameserver.evt;
using gameserver.io;
using gameserver;
using gameserver.io.player;
public static class MainEntry
{
public static void Main(string[] args)
{
Console.WriteLine("Starting game server...");
new Thread(new ThreadStart(Server.Run)).Start();
new Thread(new ThreadStart(TaskPool.Run)).Start();
new Thread(new ThreadStart(PipelineFactory.Run)).Start();
//TODO maybe pool these
}
}
Server.cs:
using gameserver.io.player;
using gameserver.io.sql;
using gameserver.model;
using gameserver.model.player;
using util;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using gameserver.io.player.pipeline;
using gameserver.evt;
using util.cache;
namespace gameserver.io
{
public class Server
{
public static TcpListener serverSocket;
public static Dictionary<int, Player> players = new Dictionary<int, Player>(Constants.MaxPlayers);
public static Database database;
public const int ListenPort = 43594;
public static bool running = true;
public static readonly Cache cache = new Cache(Constants.CacheDir);
public static void Bind()
{
serverSocket = new TcpListener(IPAddress.Parse("0.0.0.0"), ListenPort);
serverSocket.Start();
Console.WriteLine("Server started at 0.0.0.0:" + ListenPort);
}
public static void Run()
{
if (serverSocket == null)
Bind();
while(IsRunning())
{
Console.Write("serve");
var incoming = serverSocket.AcceptTcpClient();
if (incoming != null)
{
PipelineFactory.queue.Enqueue(new PlayerSocket(incoming));
}
Thread.Sleep(25);
}
}
private static void Destroy()
{
serverSocket.Stop();
//saveall players
//Environment.Exit(0);
}
public static bool Online(Player player)
{
if(player == null)
{
return false;
}
for (int i = 0; i < players.Count; i++)
{
if (player.username == players[i].username)
{
return true;
}
}
return false;
}
public static Database Database => database ?? (database = new Database());
public static bool IsRunning() => running;
}
}
TickPool.cs:
using gameserver.io;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace gameserver.evt
{
public class TaskPool
{
public static bool running = true;
public static List<PoolableTask> tasks = new List<PoolableTask>();
public static void Run()
{
do
{
long cur = Environment.TickCount;
Console.Write("tick");
foreach (PoolableTask t in tasks)
{
if (cur - t.last >= t.interval)
{
if (t == null)
continue;
t.Execute();
t.last = cur;
}
}
Thread.Sleep(100);
} while (Server.IsRunning());
}
public static void Add(PoolableTask task)
{
if(!tasks.Contains(task))
tasks.Add(task);
}
public static void Stop(PoolableTask task)
{
if(tasks.Contains(task))
tasks.Remove(task);
}
}
}
PipelineFactory.cs:
using gameserver.evt;
using gameserver.io.player.pipeline;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace gameserver.io.player
{
// simple but effective state machine for all non player model related protocol
public class PipelineFactory
{
public static Queue<PlayerSocket> queue = new Queue<PlayerSocket>(100);
private static readonly LoginPipe loginPipe = new LoginPipe();
private static readonly JaggrabPipe jgpipe = new JaggrabPipe();
private static readonly HandshakePipe handshake = new HandshakePipe();
private static readonly OnDemandPipe ondemand = new OnDemandPipe();
public static void Run()
{
while (Server.IsRunning())
{
Console.Write("pipe");
if (queue.Count() > 0)
{
var socket = queue.First();
if (socket == null || !socket.GetSocket().Connected
|| socket.state == PipeState.Play)
{
queue.Dequeue();
return;
}
switch (socket.state)
{
case PipeState.Handshake:
socket.currentPipeline = handshake;
break;
case PipeState.Jaggrab:
socket.currentPipeline = jgpipe;
break;
case PipeState.OnDemand:
socket.currentPipeline = ondemand;
break;
case PipeState.LoginResponse:
case PipeState.Block:
case PipeState.Finalize:
socket.currentPipeline = loginPipe;
break;
case PipeState.Disconnect:
//TODO: Database.saveForPlayer
socket.Close();
break;
}
try
{
if (socket.currentPipeline != null)
socket.state = socket.currentPipeline.HandleSocket(socket);
}
catch (Exception)
{
socket.Close();
queue.Dequeue();
}
}
Thread.Sleep(20);
}
}
}
}
The protocol itself really shouldn't matter just know it's all being handled asynchronously
I'm a java programmer at heart but trying to delve into C# head first so thats why my conventions might not be perfect, and I don't really know how to/dont understand intellisense documentation but at some point ill look into it
EDIT: I just wanna note that everything worked perfectly before i tried using threads to multithread this, when i had the PipelineFactory a PoolableTask object implementation, it could handle multiple connections etc and there was only the main thread calling 2 while loops handling everything in the whole server, i'm trying to spread out the load over the cpu but its not working out for me lol

Windows Service Won't Stop (C#)

I have made a Windows Service in C# that calls a python script to run. This works without a problem. However, when I go to stop the service, it gives the error "could not be stopped" and I have to manually kill it using the PID in the command line. This hasn't always been like this and I can't seem to find previous versions of my code in VS2017. What part of my code is causing the Windows service to not be able to close?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Timers;
using System.Threading;
using System.Security.Permissions;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public ThreadStart startScript;
public Thread PyScriptThread;
public ServerClass serverObject;
//-------------------------------------------------------------------------
public Service1() { InitializeComponent(); }
//-------------------------------------------------------------------------
protected override void OnStart(string[] args)
{
serverObject = new ServerClass();
PyScriptThread = new Thread(new ThreadStart(serverObject.PyScript));
var t = Task.Run(() => serverObject.PyScriptAsync(PyScriptThread));
}
//-------------------------------------------------------------------------
protected override void OnStop()
{
try
{
StreamWriter sw = new StreamWriter(#"C:\Users\bakere1\A19149\Projects\text_doc.txt", false);
sw.Write("***STOP***");
sw.Close(); //stop the script within the process
if (!serverObject.p.HasExited) //kill the process within the thread
{
serverObject.p.CancelErrorRead();
serverObject.p.CancelOutputRead();
serverObject.p.CloseMainWindow();
serverObject.p.Refresh();
serverObject.p.Close();
serverObject.p.Kill();
serverObject.p.Dispose();
}
serverObject.PyScriptAsync(PyScriptThread).Dispose();
killPyThread(PyScriptThread); //kill the overarching thread
base.OnStop();
}
catch (Exception ex)
{
if (ex is IOException || ex is ThreadInterruptedException || ex is ThreadAbortException || ex is InvalidOperationException)
{
StreamWriter errorSW = new StreamWriter(#"C:\Users\bakere1\A19149\Projects\text_doc.txt", true);
errorSW.Write("Error occurred: Stacktrace/Message/Source", ex.StackTrace, ex.Message, ex.Source);
errorSW.Close();
}
}
}
//-------------------------------------------------------------------------
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killPyThread(Thread thread)
{
thread.Interrupt();
thread.Abort();
}
}
public class ServerClass
{
public event System.EventHandler serviceChanged;
public Process p;
//-------------------------------------------------------------------------
public async Task PyScriptAsync(Thread thread)
{
await Task.Delay(10000).ConfigureAwait(false);
thread.Start();
}
public void PyScript()
{
string fileName = #"C:\Users\bakere1\A19149\Projects\BLE_Advertiser.py";
p = new Process
{
StartInfo = new ProcessStartInfo(#"C:\Python36_64\python.exe", fileName)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = false
}
};
p.Start();
p.WaitForExit();
p.CancelErrorRead();
p.CancelOutputRead();
p.CloseMainWindow();
p.Refresh();
p.Close();
p.Kill();
p.Dispose();
return;
}
//-------------------------------------------------------------------------
protected virtual void onServiceChanged()
{
serviceChanged?.Invoke(this, EventArgs.Empty);
}
}
}

Windows service stops right after launching

I have following problem with the windows service I was writing:
When I start the service it stops immediately. When I was using a console app it wasn't crushing. I have no idea what's the cause of this problem.
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ServiceModel;
using System.ServiceProcess;
using System.Configuration;
using System.Configuration.Install;
using WindowsService;
namespace WS
{
[ServiceContract(Namespace = "http://WS")]
public interface INewsReader
{
}
public class NewsReaderService : INewsReader
{
public NewsReaderService()
{
var config = new Config();
var scheduled = new Schedule(config);
scheduled.ExecuteScheduledEvents();
while (true)
{
System.Threading.Thread.Sleep(1000);
int i = 0;
}
}
}
public class NewsReaderWindowsService : ServiceBase
{
public ServiceHost serviceHost = null;
public NewsReaderWindowsService()
{
ServiceName = "NewsReaderWindowsService";
}
public static void Main()
{
ServiceBase.Run(new NewsReaderWindowsService());
}
protected override void OnStart(string[] args)
{
var thread = new System.Threading.Thread(() =>
{
while (true)
{
int i = 0;
System.Threading.Thread.Sleep(1000);
}
});
thread.Start();
serviceHost = new ServiceHost(typeof(NewsReaderService));
serviceHost.Open();
}
protected override void OnStop()
{
}
}
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "NewsReaderWindowsService";
Installers.Add(process);
Installers.Add(service);
}
}
}
Well, first of all I think your OnStart method is written badly. I can't see the reason for creating a, basicly, empty thread. You should there only initialize service (If necessary), immediately start a new thread that will work for whole time and leave the OnStart method.
Second of all use try catch block, because in my opinion somewhere in there is exception and that's why your windows service stops.
Thirdly see this example WCF Hosting with Windows Service

Does WqlEventQuery contain a constructor with 1 argument?

I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");

Categories

Resources