-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGodotServer.cs
110 lines (102 loc) · 3.93 KB
/
GodotServer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.WebSockets;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using Newtonsoft.Json;
using Microsoft.ML;
namespace godot_net_server
{
public class GodotServer
{
HttpListener httpListener;
WebSocket Socket;
MLContext mlContext = new MLContext();
OnnxModelScorer modelScorer;
static readonly CancellationTokenSource s_cts = new CancellationTokenSource();
public GodotServer(string ip = "127.0.0.1", int port = 8000)
{
modelScorer = new OnnxModelScorer("my_ppo_1_model.onnx", mlContext);
s_cts.CancelAfter(5000);
httpListener = new HttpListener();
httpListener.Prefixes.Add($"http://{ip}:{port}/");
httpListener.Start();
// Load trained model
}
public async Task Start()
{
while (Socket == null)
{
HttpListenerContext context = await httpListener.GetContextAsync();
if (context.Request.IsWebSocketRequest)
{
HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(null);
Socket = webSocketContext.WebSocket;
var message = await reset();
var action = modelScorer.Score(message.InitObservation);
while (true)
{
await render();
var action_command = action.ToList().IndexOf(action.ToList().Max());
message = await step(action_command);
action = modelScorer.Score(message.Observation);
}
}
}
}
public async Task<string> SendMessageAndGetReply(string message)
{
await Socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)),
WebSocketMessageType.Text, true, CancellationToken.None);
var incominingBuffer = new ArraySegment<byte>(new byte[1000]);
await Socket.ReceiveAsync(incominingBuffer, new CancellationToken()).ContinueWith(x =>
{
Console.WriteLine(x.Exception);
});
return Encoding.UTF8.GetString(incominingBuffer);
}
string make_command(string command)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(new { cmd = command });
}
string make_command(string command,int action)
{
return Newtonsoft.Json.JsonConvert.SerializeObject(new { cmd = command, action = new List<int>() { action } });
}
public async Task<GodotMessage> reset()
{
var resp = await SendMessageAndGetReply(make_command("reset"));
return Newtonsoft.Json.JsonConvert.DeserializeObject<GodotMessage>(resp);
}
public async Task<GodotMessage> step(int action)
{
/*
* answer = self._sendAndGetAnswer(
{'cmd': 'step', 'action': action.tolist()})
observation_np = np.array(answer['observation']).astype(np.float32)
*/
var resp = await SendMessageAndGetReply(make_command("step", action));
return Newtonsoft.Json.JsonConvert.DeserializeObject<GodotMessage>(resp); ;
}
public void close()
{
}
public async Task render()
{
var resp = await SendMessageAndGetReply(make_command("render"));
}
public class GodotMessage
{
[JsonProperty("init_observation")]
public List<float> InitObservation { get; set; }
[JsonProperty("observation")]
public List<float> Observation { get; set; }
[JsonProperty("reward")]
public float Reward{ get; set; }
}
}
}