Projekt

Obecné

Profil

« Předchozí | Další » 

Revize da9245bf

Přidáno uživatelem Eliška Mourycová před více než 3 roky(ů)

Re #8941. Implemented asynchronous listening for clients' requests.

Zobrazit rozdíly:

Server/ServerApp/Connection/ConnectionListener.cs
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
        }
Server/ServerApp/Program.cs
42 42
				return;
43 43
			}
44 44

  
45
			//ConsoleForamtingTest();
46 45

  
47 46
			
48 47

  
......
92 91
			Console.ReadLine();
93 92
        }
94 93

  
95
		private static void ConsoleForamtingTest()
96
		{
97

  
98
			Console.WriteLine("List of available commands and their description: ");
99
			Console.WriteLine("--------------------------------------------------");
100
			// data
101
			Console.WriteLine("data [OPTION] [DATE]...");
102
			Console.WriteLine("   Description: Capable of showing saved data files and downloading new ones.");
103
			Console.WriteLine("   -list: Lists currently saved data files. This list does not have to match the files which any of the predictors is trained on!");
104
			Console.WriteLine("      Example: data -list");
105
			Console.WriteLine("   -dl [startDate] [endDate]: Downloads jis, login and weather files from a specified time span. Both [startDate] and [endDate] are inclusive. Date format must be entered as [month]-[year].");
106
			Console.WriteLine("      Example: data -dl 1-2019 12-2020");
107
			Console.WriteLine("");
108

  
109
			// model
110
			Console.WriteLine("model [OPTION]");
111
			Console.WriteLine("   Description: Capable of retraining the prediction model, going back to the previous version and listing files on which the predictor was trained. ");
112
			Console.WriteLine("   -files: Lists the data files on which the currently used model was trained.");
113
			Console.WriteLine("      Example: model -files");
114
			Console.WriteLine("   -retrain: Retrains the model using the files currently saved in the data directory.");
115
			Console.WriteLine("      Example: model -retrain");
116
			Console.WriteLine("   -rollback: Switches the model back to the previous version.");
117
			Console.WriteLine("      Example: model -rollback");
118
		}
119 94

  
120 95
		private static DataDownloader DataDownloadAndRetrievalTest(Config config)
121 96
		{
......
211 186

  
212 187
		private static void ConnectionTest(IPredictionController predictionController, Config config)
213 188
		{
214
			ConnectionListener cl = new ConnectionListener(int.Parse(config.Port), predictionController);
189
			ConnectionListenerAsync cl = new ConnectionListenerAsync(int.Parse(config.Port), predictionController);
215 190
			cl.StartListening();
216 191

  
217 192
			//HttpRequestHandler hrh = new HttpRequestHandler(int.Parse(config.Port));

Také k dispozici: Unified diff