7 |
7 |
using System;
|
8 |
8 |
using System.Collections.Concurrent;
|
9 |
9 |
using System.Collections.Generic;
|
|
10 |
using System.Diagnostics;
|
10 |
11 |
using System.IO;
|
11 |
12 |
using System.Net;
|
12 |
13 |
using System.Net.Sockets;
|
... | ... | |
17 |
18 |
namespace ServerApp.Connection
|
18 |
19 |
{
|
19 |
20 |
|
20 |
|
//public class HttpListenerCallbackState
|
21 |
|
//{
|
22 |
|
// private readonly HttpListener _listener;
|
23 |
|
// private readonly AutoResetEvent _listenForNextRequest;
|
24 |
|
|
25 |
|
// public HttpListenerCallbackState(HttpListener listener)
|
26 |
|
// {
|
27 |
|
// if (listener == null) throw new ArgumentNullException("listener");
|
28 |
|
// _listener = listener;
|
29 |
|
// _listenForNextRequest = new AutoResetEvent(false);
|
30 |
|
// }
|
31 |
|
|
32 |
|
// public HttpListener Listener { get { return _listener; } }
|
33 |
|
// public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } }
|
34 |
|
//}
|
35 |
|
|
36 |
|
//public class HttpRequestHandler
|
37 |
|
//{
|
38 |
|
// private int requestCounter = 0;
|
39 |
|
// private ManualResetEvent stopEvent = new ManualResetEvent(false);
|
40 |
|
// private int PORT;
|
41 |
|
|
42 |
|
// public HttpRequestHandler(int port)
|
43 |
|
// {
|
44 |
|
// this.PORT = port;
|
45 |
|
// }
|
46 |
|
|
47 |
|
// public void ListenAsynchronously(/*IEnumerable<string> prefixes*/)
|
48 |
|
// {
|
49 |
|
// HttpListener listener = new HttpListener();
|
50 |
|
|
51 |
|
// //foreach (string s in prefixes)
|
52 |
|
// //{
|
53 |
|
// // listener.Prefixes.Add(s);
|
54 |
|
// //}
|
|
21 |
public class ConnectionListenerAsync
|
|
22 |
{
|
|
23 |
private readonly int PORT;
|
|
24 |
private IPredictionController predictionController;
|
|
25 |
//HttpListener listener;
|
|
26 |
|
|
27 |
public ConnectionListenerAsync(int port, IPredictionController predictionController)
|
|
28 |
{
|
|
29 |
this.PORT = port;
|
|
30 |
this.predictionController = predictionController;
|
|
31 |
}
|
|
32 |
|
|
33 |
|
|
34 |
public void StartListening()
|
|
35 |
{
|
|
36 |
string ip = GetLocalIPAddress();
|
|
37 |
Console.WriteLine("ip : " + ip);
|
|
38 |
HttpListener listener = new HttpListener();
|
|
39 |
//HttpListener server = new HttpListener();
|
|
40 |
//server.Prefixes.Add($"https://{ip}:{PORT}/");
|
|
41 |
listener.Prefixes.Add($"http://localhost:{PORT}/");
|
|
42 |
|
|
43 |
listener.Start();
|
|
44 |
|
|
45 |
Console.WriteLine("Listening...");
|
|
46 |
|
|
47 |
|
|
48 |
var result = listener.BeginGetContext(ListenerCallback, listener);
|
|
49 |
// result.AsyncWaitHandle.WaitOne(); // ????
|
|
50 |
}
|
|
51 |
|
|
52 |
|
|
53 |
|
|
54 |
private void ListenerCallback(IAsyncResult result)
|
|
55 |
{
|
|
56 |
Console.WriteLine("in ListenerCallback");
|
|
57 |
HttpListener listener = (HttpListener)result.AsyncState;
|
|
58 |
|
|
59 |
// Call EndGetContext to complete the asynchronous operation.
|
|
60 |
HttpListenerContext context = listener.EndGetContext(result);
|
|
61 |
|
|
62 |
// tell listener to get the next context directly.
|
|
63 |
listener.BeginGetContext(ListenerCallback, listener);
|
|
64 |
|
|
65 |
// Obtain a request object.
|
|
66 |
HttpListenerRequest request = context.Request;
|
|
67 |
// Obtain a response object.
|
|
68 |
HttpListenerResponse response = context.Response;
|
|
69 |
|
|
70 |
// Simulate work
|
|
71 |
//Thread.Sleep(5000);
|
55 |
72 |
|
56 |
|
// listener.Prefixes.Add($"http://localhost:{PORT}/");
|
57 |
73 |
|
58 |
|
// listener.Start();
|
59 |
|
// Console.WriteLine("Listening...");
|
60 |
|
// HttpListenerCallbackState state = new HttpListenerCallbackState(listener);
|
61 |
|
// ThreadPool.QueueUserWorkItem(Listen, state);
|
62 |
|
// }
|
63 |
74 |
|
64 |
|
// public void StopListening()
|
65 |
|
// {
|
66 |
|
// stopEvent.Set();
|
67 |
|
// }
|
|
75 |
// add the headers and everything:
|
|
76 |
response.AddHeader("Access-Control-Allow-Credentials", "true");
|
|
77 |
response.AddHeader("Access-Control-Expose-Headers", "ETag");
|
|
78 |
response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
|
|
79 |
response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
80 |
response.AddHeader("Access-Control-Allow-Origin", "*");
|
68 |
81 |
|
|
82 |
string responseString = "";
|
|
83 |
// Construct a response.
|
|
84 |
if (context.Request.HttpMethod == "GET") // when client says download
|
|
85 |
{
|
|
86 |
Console.WriteLine("received GET request");
|
|
87 |
responseString = ConstructGETResponse();
|
69 |
88 |
|
70 |
|
// private void Listen(object state)
|
71 |
|
// {
|
72 |
|
// HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state;
|
|
89 |
}
|
|
90 |
else if (context.Request.HttpMethod == "POST") // when client says upload
|
|
91 |
{
|
|
92 |
Console.WriteLine("received POST request");
|
|
93 |
string text;
|
|
94 |
using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
|
|
95 |
text = reader.ReadToEnd();
|
|
96 |
string requestString = HttpUtility.UrlDecode(text);
|
73 |
97 |
|
74 |
|
// while (callbackState.Listener.IsListening)
|
75 |
|
// {
|
76 |
|
// callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState);
|
77 |
|
// int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent });
|
|
98 |
responseString = ConstructPOSTResponse(requestString);
|
78 |
99 |
|
79 |
|
// if (n == 1)
|
80 |
|
// {
|
81 |
|
// // stopEvent was signalled
|
82 |
|
// callbackState.Listener.Stop();
|
83 |
|
// break;
|
84 |
|
// }
|
85 |
|
// }
|
86 |
|
// }
|
87 |
100 |
|
88 |
|
// private void ListenerCallback(IAsyncResult ar)
|
89 |
|
// {
|
90 |
|
// HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState;
|
91 |
|
// HttpListenerContext context = null;
|
|
101 |
}
|
|
102 |
else
|
|
103 |
{
|
|
104 |
Console.WriteLine("received request other than GET or POST");
|
92 |
105 |
|
93 |
|
// int requestNumber = Interlocked.Increment(ref requestCounter);
|
|
106 |
}
|
94 |
107 |
|
95 |
|
// try
|
96 |
|
// {
|
97 |
|
// context = callbackState.Listener.EndGetContext(ar);
|
98 |
|
// }
|
99 |
|
// catch (Exception ex)
|
100 |
|
// {
|
101 |
|
// return;
|
102 |
|
// }
|
103 |
|
// finally
|
104 |
|
// {
|
105 |
|
// callbackState.ListenForNextRequest.Set();
|
106 |
|
// }
|
107 |
108 |
|
108 |
|
// if (context == null) return;
|
109 |
109 |
|
110 |
110 |
|
111 |
|
// HttpListenerRequest request = context.Request;
|
112 |
111 |
|
113 |
|
// if (request.HasEntityBody)
|
114 |
|
// {
|
115 |
|
// using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
|
116 |
|
// {
|
117 |
|
// string requestData = sr.ReadToEnd();
|
|
112 |
//string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
|
|
113 |
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
|
118 |
114 |
|
119 |
|
// //Stuff I do with the request happens here
|
120 |
|
// }
|
121 |
|
// }
|
|
115 |
// Get a response stream and write the response to it.
|
|
116 |
response.ContentLength64 = buffer.Length;
|
|
117 |
System.IO.Stream output = response.OutputStream;
|
|
118 |
output.Write(buffer, 0, buffer.Length);
|
122 |
119 |
|
|
120 |
// Close the output stream.
|
|
121 |
output.Close();
|
|
122 |
response.Close();
|
123 |
123 |
|
124 |
|
// try
|
125 |
|
// {
|
126 |
|
// using (HttpListenerResponse response = context.Response)
|
127 |
|
// {
|
128 |
|
// Console.WriteLine("dealing with response");
|
129 |
|
// //Thread.Sleep(10000);
|
130 |
|
// //response stuff happens here
|
131 |
|
// string responseString = "Ok";
|
|
124 |
Console.WriteLine("At the end of ListenerCallback");
|
132 |
125 |
|
133 |
|
// byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
134 |
|
// response.ContentLength64 = buffer.LongLength;
|
135 |
|
// response.OutputStream.Write(buffer, 0, buffer.Length);
|
136 |
|
// response.Close();
|
137 |
|
// }
|
138 |
|
// }
|
139 |
|
// catch (Exception e)
|
140 |
|
// {
|
141 |
|
// }
|
142 |
|
// }
|
143 |
|
//}
|
|
126 |
}
|
144 |
127 |
|
145 |
128 |
|
|
129 |
private string ConstructGETResponse()
|
|
130 |
{
|
|
131 |
Console.WriteLine("Constructiing a response for GET request.");
|
|
132 |
|
|
133 |
int rand = new Random().Next(1, 10);
|
|
134 |
string msg = "This is a response from the server :) " + rand;
|
146 |
135 |
|
|
136 |
Response xmlResp = Response.Randomize();
|
|
137 |
var xml = XmlCommunication.Serialize(xmlResp);
|
147 |
138 |
|
|
139 |
return xml;
|
148 |
140 |
|
149 |
141 |
|
|
142 |
}
|
150 |
143 |
|
|
144 |
private string ConstructPOSTResponse(string requestString)
|
|
145 |
{
|
|
146 |
Console.WriteLine("Constructiing a response for POST request.");
|
|
147 |
Console.WriteLine("Request string: ");
|
|
148 |
Console.WriteLine(requestString);
|
151 |
149 |
|
152 |
150 |
|
153 |
151 |
|
154 |
|
public class ConnectionListener
|
155 |
|
{
|
|
152 |
// prepare the type:
|
|
153 |
Request newRequest = new Request();
|
|
154 |
Request requestDeserialized = null;
|
|
155 |
try
|
|
156 |
{
|
|
157 |
requestDeserialized = XmlCommunication.Deserialize(newRequest, requestString);
|
|
158 |
}
|
|
159 |
catch
|
|
160 |
{
|
|
161 |
Console.WriteLine("wrong format of request!");
|
|
162 |
|
|
163 |
// don't bother to send anything:
|
|
164 |
return string.Empty;
|
|
165 |
}
|
|
166 |
|
|
167 |
|
|
168 |
// get the prediction from the model:
|
|
169 |
Response responsePrediction = predictionController.Predict(requestDeserialized);
|
|
170 |
|
|
171 |
|
|
172 |
// build the xml from the prediction: - TODO mbe an exception can happen here as well? - it shouldnt
|
|
173 |
return XmlCommunication.Serialize(responsePrediction);
|
|
174 |
|
|
175 |
|
|
176 |
|
|
177 |
}
|
|
178 |
|
|
179 |
|
|
180 |
private string GetLocalIPAddress()
|
|
181 |
{
|
|
182 |
var host = Dns.GetHostEntry(Dns.GetHostName());
|
|
183 |
foreach (var ip in host.AddressList)
|
|
184 |
{
|
|
185 |
if (ip.AddressFamily == AddressFamily.InterNetwork)
|
|
186 |
{
|
|
187 |
return ip.ToString();
|
|
188 |
}
|
|
189 |
}
|
|
190 |
throw new Exception("No network adapters with an IPv4 address in the system!");
|
|
191 |
}
|
|
192 |
}
|
|
193 |
|
|
194 |
|
|
195 |
|
|
196 |
|
|
197 |
|
|
198 |
|
|
199 |
|
|
200 |
|
|
201 |
|
|
202 |
|
|
203 |
|
|
204 |
|
|
205 |
|
|
206 |
|
|
207 |
|
|
208 |
|
|
209 |
|
|
210 |
|
|
211 |
|
|
212 |
|
|
213 |
|
|
214 |
|
|
215 |
|
|
216 |
|
|
217 |
|
|
218 |
|
|
219 |
// -----------------------------------------------------------------------------
|
|
220 |
|
|
221 |
public class ConnectionListener
|
|
222 |
{
|
156 |
223 |
private readonly int PORT;
|
157 |
224 |
private IPredictionController predictionController;
|
158 |
225 |
|
... | ... | |
162 |
229 |
this.predictionController = predictionController;
|
163 |
230 |
}
|
164 |
231 |
|
|
232 |
|
165 |
233 |
public void StartListening()
|
166 |
234 |
{
|
167 |
235 |
string ip = GetLocalIPAddress();
|
168 |
236 |
Console.WriteLine("ip : " + ip);
|
169 |
237 |
HttpListener server = new HttpListener();
|
170 |
|
server.Prefixes.Add($"https://{ip}:{PORT}/");
|
171 |
|
//server.Prefixes.Add($"http://localhost:{PORT}/");
|
|
238 |
//server.Prefixes.Add($"https://{ip}:{PORT}/");
|
|
239 |
server.Prefixes.Add($"http://localhost:{PORT}/");
|
172 |
240 |
|
173 |
241 |
server.Start();
|
174 |
242 |
|
... | ... | |
178 |
246 |
{
|
179 |
247 |
Console.WriteLine("Waiting for a client request...");
|
180 |
248 |
|
|
249 |
//ThreadPool.QueueUserWorkItem(Process, server.GetContext());
|
181 |
250 |
HttpListenerContext context = server.GetContext();
|
182 |
251 |
|
183 |
252 |
|
... | ... | |
247 |
316 |
context.Response.Close();
|
248 |
317 |
continue;
|
249 |
318 |
}
|
250 |
|
|
|
319 |
|
251 |
320 |
|
252 |
321 |
// response headers:
|
253 |
322 |
HttpListenerResponse response = context.Response;
|
... | ... | |
358 |
427 |
public Response ClientResponse;
|
359 |
428 |
}
|
360 |
429 |
|
361 |
|
public class ConnectionListenerMulti
|
|
430 |
public class ConnectionListenerQueue
|
362 |
431 |
{
|
363 |
432 |
private readonly int PORT;
|
364 |
433 |
private ConcurrentDictionary<int, ClientService> readyRequests;
|
365 |
434 |
private ConcurrentQueue<ClientService> waitingRequests;
|
366 |
435 |
|
367 |
436 |
|
368 |
|
public ConnectionListenerMulti(int port)
|
|
437 |
public ConnectionListenerQueue(int port)
|
369 |
438 |
{
|
370 |
439 |
this.PORT = port;
|
371 |
440 |
}
|
Re #8941. Implemented asynchronous listening for clients' requests.