source: 2016/koodauskerho/TaneliL/NetworkConnection.cs @ 10334

Revision 8302, 4.5 KB checked in by sieerinn, 3 years ago (diff)
Line 
1using System;
2using System.IO;
3using System.Linq;
4using System.Net.Sockets;
5using System.Threading;
6using System.Runtime.Serialization.Formatters.Binary;
7
8
9public class NetworkConnection
10{
11    private readonly byte[] guidBytes;
12    private readonly TcpClient client;
13    private readonly CancellationTokenSource cancelSource;
14    private NetworkStream stream;
15    private Thread receiveThread;
16    private Guid guid;
17    private string gameName;
18
19    public delegate void MessageReceived(Guid id, string message);
20    public delegate void ConnectionChanged(Guid id);
21
22    public event MessageReceived OnMessageReceive;
23    public event ConnectionChanged OnConnect;
24    public event ConnectionChanged OnDisconnect;
25
26    public bool Connected { get; private set; }
27
28    public enum MessageType
29    {
30        Connected = 0, Disconnected, Message
31    }
32
33    public NetworkConnection(string gameName)
34    {
35        Connected = false;
36        this.gameName = gameName;
37        guid = Guid.NewGuid();
38        guidBytes = guid.ToByteArray();
39        cancelSource = new CancellationTokenSource();
40        client = new TcpClient();
41    }
42
43    public void Connect(string ip, int port)
44    {
45        client.Connect(ip, port); // TODO: try
46        stream = client.GetStream();
47        receiveThread = new Thread(() => ReceiveThread(cancelSource.Token));
48        receiveThread.Start();
49        Connected = true;
50        Send(MessageType.Connected);
51    }
52
53    public void Close()
54    {
55        if (!Connected) return;
56        Send(MessageType.Disconnected);
57        cancelSource.Cancel();
58        receiveThread.Join();
59        stream.Close();
60        client.Client.Close();
61        client.Close();
62        Connected = false;
63    }
64
65    private void Send(MessageType type)
66    {
67        var mstream = new MemoryStream();
68        var writer = new BinaryWriter(mstream);
69        writer.Write((byte)type);
70        writer.Write(guidBytes, 0, guidBytes.Length);
71        writer.Write(gameName);
72        var sendBytes = mstream.ToArray();
73        stream.Write(sendBytes, 0, sendBytes.Length);
74    }
75
76    private void SendWithMessage(MessageType type, string message)
77    {
78        var mstream = new MemoryStream();
79        var writer = new BinaryWriter(mstream);
80
81        writer.Write((byte)type);
82        writer.Write(guidBytes, 0, guidBytes.Length);
83        writer.Write(gameName);
84        writer.Write(message);
85
86        var sendBytes = mstream.ToArray();
87        stream.Write(sendBytes, 0, sendBytes.Length);
88        stream.Flush();
89    }
90
91    public void SendMessage(string message)
92    {
93        SendWithMessage(MessageType.Message, message);
94    }
95
96    public T DeserializeFromString<T>(string settings) where T : class
97    {
98        var bytes = Convert.FromBase64String(settings);
99        using (var mstream = new MemoryStream(bytes))
100        {
101            var formatter = new BinaryFormatter();
102            mstream.Seek(0, SeekOrigin.Begin);
103            return formatter.Deserialize(mstream) as T;
104        }
105    }
106
107    public void SendObject(object serializableObject)
108    {
109        using (var mstream = new MemoryStream())
110        {
111            var formatter = new BinaryFormatter();
112            formatter.Serialize(mstream, serializableObject);
113            mstream.Flush();
114            mstream.Position = 0;
115            SendMessage(Convert.ToBase64String(mstream.ToArray()));
116        }
117    }
118
119    private void ReceiveThread(CancellationToken cancelToken)
120    {
121        while (!cancelToken.IsCancellationRequested)
122        {
123            if (client.Available <= 0) continue;
124
125            var receivedBytes = new byte[2048];
126            stream.Read(receivedBytes, 0, 2048);
127            var mstream = new MemoryStream(receivedBytes);
128            var reader = new BinaryReader(mstream);
129           
130            var messageType = (MessageType)reader.ReadByte();
131            var senderGuid = new Guid(reader.ReadBytes(guidBytes.Length));
132            var game = reader.ReadString();
133
134            if (messageType == MessageType.Message && OnMessageReceive != null)
135            {
136                var message = reader.ReadString();
137                OnMessageReceive(senderGuid, message);
138            }
139
140            if (messageType == MessageType.Connected && OnConnect != null)
141            {
142                OnConnect(senderGuid);
143            }
144
145            if (messageType == MessageType.Disconnected && OnDisconnect != null)
146            {
147                OnDisconnect(senderGuid);
148            }
149        }
150    }
151}
Note: See TracBrowser for help on using the repository browser.