3 using SiliconStudio.Core.Diagnostics;
4 #if !SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME
6 using System.Collections.Generic;
10 using System.Net.Sockets;
12 using System.Threading;
13 using System.Runtime.Serialization.Formatters.Binary;
14 using System.Threading.Tasks;
15 using System.Runtime.CompilerServices;
16 using System.Collections;
17 using SiliconStudio.Core.Serialization;
23 namespace SiliconStudio.
Paradox.Engine.Network
29 private TaskCompletionSource<bool> clientConnected;
30 private bool isServer;
31 private NetworkStream socketStream;
32 private BinaryReader socketBinaryReader;
33 private BinaryWriter socketBinaryWriter;
34 private readonly ManualResetEvent allDone =
new ManualResetEvent(
false);
35 private readonly Dictionary<int, TaskCompletionSource<SocketMessage>> packetCompletionTasks =
new Dictionary<int, TaskCompletionSource<SocketMessage>>();
37 Dictionary<Type, Tuple<Action<object>,
bool>> packetHandlers =
new Dictionary<Type, Tuple<Action<object>,
bool>>();
41 public void AddPacketHandler<T>(Action<T> handler,
bool oneTime =
false)
45 packetHandlers.Add(typeof(T), Tuple.Create<Action<object>,
bool>((obj) => handler((T)obj), oneTime));
49 public void Send(
object obj)
51 var memoryStream =
new MemoryStream();
53 binaryWriter.SerializeExtended(obj, ArchiveMode.Serialize, null);
54 var memoryBuffer = memoryStream.ToArray();
56 socketBinaryWriter.Write(memoryBuffer.Length);
59 for (
int i = 0; i < (memoryBuffer.Length + 1023) / 1024; ++i)
60 socketStream.Write(memoryStream.GetBuffer(), i * 1024, Math.Min(1024, memoryBuffer.Length - i * 1024));
70 clientConnected =
new TaskCompletionSource<bool>();
71 new Thread(
SafeAction.
Wrap(() => ClientThread(address, port))).Start();
77 var tcs =
new TaskCompletionSource<SocketMessage>();
78 query.StreamId = SocketMessage.NextStreamId + (isServer ? 0x4000000 : 0);
79 lock (packetCompletionTasks)
81 packetCompletionTasks.Add(query.StreamId, tcs);
87 async
void ClientThread(IPAddress address,
int port)
93 var localEP =
new IPEndPoint(address, port);
95 var socket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
96 socket.NoDelay =
true;
97 socket.Connect(localEP);
99 SetSocketStream(
new NetworkStream(socket));
101 clientConnected.TrySetResult(
true);
106 Console.WriteLine(
"Error connecting: " + e);
109 await TaskEx.Delay(1000);
113 void ServerThread(
int port)
117 var localEP =
new IPEndPoint(IPAddress.Any, port);
119 var listener =
new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
120 listener.NoDelay =
true;
123 listener.Bind(localEP);
129 Console.WriteLine(
"Waiting for a connection...");
130 listener.BeginAccept(AcceptCallback, listener);
137 Console.WriteLine(e.ToString());
141 void AcceptCallback(IAsyncResult ar)
147 var listener = (Socket)ar.AsyncState;
148 var handler = listener.EndAccept(ar);
150 var clientSocketContext =
new SocketContext();
151 clientSocketContext.SetSocketStream(
new NetworkStream(handler));
152 clientSocketContext.isServer =
true;
154 if (Connected != null)
155 Connected(clientSocketContext);
157 clientSocketContext.MessageLoop();
160 Console.WriteLine(e.ToString());
169 var remaining = socketBinaryReader.ReadInt32();
170 var buffer =
new byte[remaining];
172 while (remaining > 0)
174 int read = socketStream.Read(buffer, offset, remaining);
180 binaryReader.SerializeExtended<
object>(ref obj, ArchiveMode.Deserialize, null);
181 if (obj is SocketMessage)
183 var socketMessage = (SocketMessage)obj;
184 ProcessMessage(socketMessage);
187 Tuple<Action<object>,
bool> handler;
188 lock (packetHandlers)
190 handlerFound = packetHandlers.TryGetValue(obj.GetType(), out handler);
193 if (handlerFound && handler.Item2)
195 packetHandlers.Remove(obj.GetType());
206 void SetSocketStream(NetworkStream socketStream)
208 this.socketStream = socketStream;
209 socketBinaryReader =
new BinaryReader(this.socketStream);
210 socketBinaryWriter =
new BinaryWriter(this.socketStream);
213 void ProcessMessage(SocketMessage socketMessage)
215 TaskCompletionSource<SocketMessage> tcs;
216 lock (packetCompletionTasks)
218 packetCompletionTasks.TryGetValue(socketMessage.StreamId, out tcs);
220 packetCompletionTasks.Remove(socketMessage.StreamId);
223 tcs.TrySetResult(socketMessage);
Action< SocketContext > Connected
static ThreadStart Wrap(ThreadStart action, [CallerFilePath] string sourceFilePath="", [CallerMemberName] string memberName="", [CallerLineNumber] int sourceLineNumber=0)
System.Threading.Tasks.Task Task
Implements SerializationStream as a binary writer.
void StartServer(int port)
Implements SerializationStream as a binary reader.
async Task< SocketMessage > SendReceiveAsync(SocketMessage query)
async Task StartClient(IPAddress address, int port)