Advertisement
Guest User

JsonClient

a guest
Feb 25th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.64 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using Newtonsoft.Json;
  7. using TcpJsonLib.EventHandlers;
  8.  
  9. namespace TcpJsonLib
  10. {
  11.     public class JsonClient : IDisposable
  12.     {
  13.         /// <summary>
  14.         /// Sets whether or not the client should automatically attempt to reconnect after a specified amount of ms (see <see cref="AutoReconnectDelay"/>).
  15.         /// </summary>
  16.         public bool AutoReconnect { get; set; }
  17.  
  18.         /// <summary>
  19.         /// The amount of miliseconds to wait before attempting to reconnect. (if <see cref="AutoReconnect"/> is set to true).
  20.         /// </summary>
  21.         public int AutoReconnectDelay { get; set; } = 1000;
  22.  
  23.         private Socket client;
  24.  
  25.         public Socket Client
  26.         {
  27.             get { return client; }
  28.             private set
  29.             {
  30.                 client = value;
  31.                 if (client.Connected)
  32.                     BeginReceive();
  33.             }
  34.         }
  35.  
  36.         public delegate void ClientConnectedEventHandler(ClientConnectedEventArgs e);
  37.         public event ClientConnectedEventHandler ClientConnected;
  38.  
  39.         public delegate void ClientDisconnectedEventHandler(ClientDisconnectedEventArgs e);
  40.         public event ClientDisconnectedEventHandler ClientDisonnected;
  41.  
  42.         private byte[] buffer;
  43.         const int BUFFER_SIZE = 1024;
  44.         private byte[] lenBuffer;
  45.         const int LEN_BUFFER_SIZE = 4;
  46.  
  47.         public bool Connected => Client?.Connected ?? false;
  48.  
  49.         private MemoryStream ms;
  50.  
  51.         private Dictionary<string, Action<JsonClient, dynamic>> OnReceiveActions;
  52.  
  53.         public JsonClient()
  54.         {
  55.             buffer = new byte[BUFFER_SIZE];
  56.             lenBuffer = new byte[LEN_BUFFER_SIZE];
  57.             OnReceiveActions = new Dictionary<string, Action<JsonClient, dynamic>>();
  58.             client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  59.         }
  60.  
  61.         public JsonClient(IPAddress address, int port) : this()
  62.         {
  63.             Connect(address, port);
  64.         }
  65.  
  66.         public static implicit operator JsonClient(TcpClient client)
  67.         {
  68.             return new JsonClient { Client = client.Client };
  69.         }
  70.  
  71.         /// <summary>
  72.         /// Sends a packet to the remote host.
  73.         /// </summary>
  74.         /// <param name="key"></param>
  75.         /// <param name="json"></param>
  76.         public void Emit(string key, dynamic json)
  77.         {
  78.             using (MemoryStream ms = new MemoryStream())
  79.             {
  80.                 ms.Position = 4L;
  81.                 using (BinaryWriter bw = new BinaryWriter(ms))
  82.                 {
  83.                     bw.Write(key);
  84.  
  85.                     string jsonStr = JsonConvert.SerializeObject(json);
  86.  
  87.                     bw.Write(jsonStr);
  88.                     ms.Position = 0L;
  89.                     bw.Write((int)ms.Length);
  90.                 }
  91.                 byte[] data = ms.ToArray();
  92.                 Client.BeginSend(data, 0, data.Length, SocketFlags.None, WriteCallback, null);
  93.             }
  94.         }
  95.  
  96.         private void WriteCallback(IAsyncResult ar)
  97.         {
  98.             try { Client.EndSend(ar); }
  99.             catch { }
  100.         }
  101.  
  102.         /// <summary>
  103.         /// Establishes a connection with the remote host.
  104.         /// </summary>
  105.         /// <param name="address"></param>
  106.         /// <param name="port"></param>
  107.         public void Connect(IPAddress address, int port)
  108.         {
  109.             Client.BeginConnect(new IPEndPoint(address, port), ConnectCallback, null);
  110.         }
  111.  
  112.         /// <summary>
  113.         /// Adds a listener for incoming packets, and invokes the action with the packet data.
  114.         /// </summary>
  115.         /// <param name="key"></param>
  116.         /// <param name="action"></param>
  117.         public void AddListener(string key, Action<JsonClient, dynamic> action)
  118.         {
  119.             if (OnReceiveActions.ContainsKey(key))
  120.                 throw new Exception("A listener with this key is already present.");
  121.             OnReceiveActions.Add(key, action);
  122.         }
  123.  
  124.         /// <summary>
  125.         /// Remove a listener for incoming packets.
  126.         /// </summary>
  127.         /// <param name="key"></param>
  128.         public void RemoveListener(string key)
  129.         {
  130.             if (!OnReceiveActions.ContainsKey(key))
  131.                 throw new Exception("No existing listener with this key could be found.");
  132.             OnReceiveActions.Remove(key);
  133.         }
  134.  
  135.         private void ConnectCallback(IAsyncResult ar)
  136.         {
  137.             try
  138.             {
  139.                 Client.EndConnect(ar);
  140.                 ClientConnected?.Invoke(new ClientConnectedEventArgs(this, client.RemoteEndPoint));
  141.                 BeginReceive();
  142.             }
  143.             catch (SocketException ex)
  144.             {
  145.                 throw ex;
  146.             }
  147.         }
  148.  
  149.         private void ReceiveCallback(IAsyncResult ar)
  150.         {
  151.             try
  152.             {
  153.                 int len = Client.EndReceive(ar);
  154.  
  155.                 if (len <= 0)
  156.                 {
  157.                     Close();
  158.                     return;
  159.                 }
  160.                 int toReceive = BitConverter.ToInt32(lenBuffer, 0);
  161.                 ms = new MemoryStream();
  162.                 Client.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceivePacketCallback, toReceive - LEN_BUFFER_SIZE);
  163.             }
  164.             catch { Close(); }
  165.         }
  166.  
  167.         private void ReceivePacketCallback(IAsyncResult ar)
  168.         {
  169.             try
  170.             {
  171.                 int len = Client.EndReceive(ar);
  172.                 int toReceive = (int)ar.AsyncState - len;
  173.  
  174.                 ms.Write(buffer, 0, len);
  175.  
  176.                 if (toReceive > 0)
  177.                 {
  178.                     Client.BeginReceive(buffer, 0, Math.Min(BUFFER_SIZE, toReceive), SocketFlags.None, ReceivePacketCallback, toReceive);
  179.                     return;
  180.                 }
  181.                 ms.Position = 0L;
  182.                 using (BinaryReader br = new BinaryReader(ms))
  183.                 {
  184.                     string key = br.ReadString();
  185.                     string dataStr = br.ReadString();
  186.  
  187.                     dynamic data = JsonConvert.DeserializeObject(dataStr);
  188.  
  189.                     if (OnReceiveActions.ContainsKey(key))
  190.                         OnReceiveActions[key].Invoke(this, data);
  191.                 }
  192.                 ms.Close();
  193.             }
  194.             catch (SocketException) { Close(); }
  195.             catch { }
  196.             finally { BeginReceive(); }
  197.         }
  198.  
  199.         private void BeginReceive()
  200.         {
  201.             try
  202.             {
  203.                 Client.BeginReceive(lenBuffer, 0, LEN_BUFFER_SIZE, SocketFlags.None, ReceiveCallback, null);
  204.             }
  205.             catch { }
  206.         }
  207.  
  208.         /// <summary>
  209.         /// Close the connection with a remote host.
  210.         /// </summary>
  211.         public void Close()
  212.         {
  213.             if (client != null)
  214.             {
  215.                 client?.Close();
  216.                 ClientDisonnected?.Invoke(new ClientDisconnectedEventArgs(this));
  217.             }
  218.         }
  219.  
  220.         public void Dispose()
  221.         {
  222.             client?.Close();
  223.         }
  224.     }
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement