HttpServer StartServer(string addressAndOptionalPort)
{
// string host = "http://" + addressAndOptionalPort;
// var addressUri = new System.Uri(addressAndOptionalPort);
// int port = addressUri.Port;
// string address = Unwrap(addressUri.Host);
//server = new HttpServer (5963, true);
//server = new HttpServer (System.Net.IPAddress.Parse ("127.0.0.1"), 4649);
//server = new HttpServer (System.Net.IPAddress.Parse ("127.0.0.1"), 5963, true);
//server = new HttpServer ("http://localhost:4649");
//server = new HttpServer ("https://localhost:5963");
//server = new HttpServer(System.Net.IPAddress.Parse("127.0.0.1"), 18679);
// HttpServer server = new HttpServer(System.Net.IPAddress.Parse(address), port);
HttpServer server = new HttpServer(addressAndOptionalPort);
//server.Log.Level = LogLevel.Trace;
//server.Log.File = "/Users/gregg/temp/foo.txt";
#if FALSE
// To change the logging level.
server.Log.Level = LogLevel.Trace;
// To change the wait time for the response to the WebSocket Ping or Close.
server.WaitTime = TimeSpan.FromSeconds (2);
#endif
/* To provide the secure connection.
var cert = ConfigurationManager.AppSettings["ServerCertFile"];
var passwd = ConfigurationManager.AppSettings["CertFilePassword"];
server.SslConfiguration.ServerCertificate = new X509Certificate2 (cert, passwd);
*/
/* To provide the HTTP Authentication (Basic/Digest).
server.AuthenticationSchemes = AuthenticationSchemes.Basic;
server.Realm = "WebSocket Test";
server.UserCredentialsFinder = id => {
var name = id.Name;
// Return user name, password, and roles.
return name == "nobita"
? new NetworkCredential (name, "password", "gunfighter")
: null; // If the user credentials aren't found.
};
*/
// Set the document root path.
// server.RootPath = ConfigurationManager.AppSettings["RootPath"];
// Set the HTTP GET request event.
server.OnGet += (sender, e) =>
{
var req = e.Request;
var res = e.Response;
var uri = req.Url;
var path = uri.AbsolutePath;
if (String.IsNullOrEmpty(path))
{
path = "/";
}
if (path == "/")
{
path += "index.html";
}
//Debug.Log("HFTWebServer: " + uri.ToString() + " ========================");
//Debug.Log("remote ip: " + req.RemoteEndPoint.Address.ToString());
//Debug.Log("Num Headers: " + req.Headers.Count);
//foreach(string key in req.Headers.AllKeys)
//{
// string value = req.Headers.Get(key);
// Debug.Log("Header: " + key + " = " + value);
//}
m_log.Info(path);
if (!m_getRouter.Route(path, req, res))
{
throw new System.InvalidOperationException("no route for request: " + path);
}
};
server.OnOptions += (sender, e) =>
{
var res = e.Response;
res.AddHeader("Access-Control-Allow-Origin", "*");
res.AddHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
res.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept");
res.AddHeader("Access-Control-Allow-Credentials", "false");
res.AddHeader("Access-Control-Max-Age", "86400");
res.StatusCode = (int)HttpStatusCode.OK;
res.WriteContent(new byte[0]);
};
server.OnPost += (sender, e) =>
{
var req = e.Request;
var res = e.Response;
Stream dataStream = req.InputStream;
StreamReader reader = new StreamReader(dataStream);
string result = reader.ReadToEnd();
reader.Close();
dataStream.Close();
// This is hacky. Basically websever repsonds long before
// the game is ready to accept players. So players connect
// and get rejected (no such game). There's probably a better
// solution but this lets the game check if the server is
// running immediately but controllers won't be told
// until the game has registered with the server.
//
// The better solution is probably try to figure out
// why the game doesn't connect first.
//
// Note, nornally you'd start a game, then ask players
// to join. The case above happens while developing. You
// run the game once. Open a browser window. Quit the game.
// The browser is now trying to reconnect. The moment you
// run the game the browser reconnects but the system
// isn't fully ready yet.
PostCmd cmd = null;
try
{
cmd = deserializer_.Deserialize<PostCmd>(result);
}
catch (System.Exception)
{
m_log.Warn("could't deseralize PostCmd:" + result);
}
if (cmd == null || cmd.cmd == null)
{
res.ContentType = "application/json";
res.StatusCode = (int)HttpStatusCode.BadRequest;
res.WriteContent(System.Text.Encoding.UTF8.GetBytes("{\"error\":\"bad command data: " + cmd.cmd + "\"}"));
}
else if (cmd.cmd == "happyFunTimesPingForGame")
{
m_webServerUtils.SendJsonBytes(res, m_ping);
return;
}
else if (cmd.cmd == "happyFunTimesPing")
{
// Yes reaching up this far is shit :(
if (!HFTGameManager.GetInstance().HaveGame())
{
res.StatusCode = (int)HttpStatusCode.NotFound;
return;
}
m_webServerUtils.SendJsonBytes(res, m_ping);
return;
}
else if (cmd.cmd == "happyFunTimesRedir")
{
string controllerPath = m_gamePath + m_options.controllerFilename;
string redirStr = Serializer.Serialize(new Redir(controllerPath));
m_redir = System.Text.Encoding.UTF8.GetBytes(redirStr);
m_webServerUtils.SendJsonBytes(res, m_redir);
return;
}
else
{
res.ContentType = "application/json";
res.StatusCode = (int)HttpStatusCode.BadRequest;
res.WriteContent(System.Text.Encoding.UTF8.GetBytes("{\"error\":\"unknown cmd: " + cmd.cmd + "\"}"));
}
// TODO: use router
};
// Not to remove the inactive WebSocket sessions periodically.
//server.KeepClean = false;
// To resolve to wait for socket in TIME_WAIT state.
//server.ReuseAddress = true;
// Add the WebSocket services.
// server.AddWebSocketService<Echo> ("/Echo");
// server.AddWebSocketService<Chat> ("/Chat");
server.AddWebSocketService<HFTSocket>("/");
/* Add the WebSocket service with initializing.
server.AddWebSocketService<Chat> (
"/Chat",
() => new Chat ("Anon#") {
// To send the Sec-WebSocket-Protocol header that has a subprotocol name.
Protocol = "chat",
// To emit a WebSocket.OnMessage event when receives a ping.
EmitOnPing = true,
// To ignore the Sec-WebSocket-Extensions header.
IgnoreExtensions = true,
// To validate the Origin header.
OriginValidator = val => {
// Check the value of the Origin header, and return true if valid.
Uri origin;
return !val.IsNullOrEmpty () &&
Uri.TryCreate (val, UriKind.Absolute, out origin) &&
origin.Host == "localhost";
},
// To validate the Cookies.
CookiesValidator = (req, res) => {
// Check the Cookies in 'req', and set the Cookies to send to the client with 'res'
// if necessary.
foreach (Cookie cookie in req) {
cookie.Expired = true;
res.Add (cookie);
}
return true; // If valid.
}
});
*/
server.Start();
if (server.IsListening)
{
m_log.Info(String.Format("Listening on {0} port {1}, and providing WebSocket services:", server.Address, server.Port));
//foreach (var path in server.WebSocketServices.Paths) Debug.Log(String.Format("- {0}", path));
}
return server;
}