Hi,
WCF war mir immer zu umständlich und ich hatte zu wenig Kontrolle, außerdem sind Events extrem kompliziert zu implementieren und ein gescheites Authentifizierungssystem wollte auch nicht klappen, also habe ich diese kleine Bibliothek geschrieben, welche über egal welche Verbindung Methoden und Funktionen mit oder ohne Parameter aufrufen kann. Das ganze ist sehr einfach zu benutzen:
Auf der Serverseite habt ihr folgenden Code:
und auf der Client-Seite dann folgenden Code:
Das ist beinah auch schon alles. Jetzt müssen nur noch die einzelnen Punkte miteinander vernetzt werden:
und schon ist es fertig. Es können natürlich nicht nur Strings und andere primitive Datentypen übertragen werden, sondern auch alle Klassen und sogar abstrakte Klassen sind ohne Probleme möglich (die Typen der abstrakten Klassen müssen dann beim Senden und Empfangen angegeben werden, einfach die Überladung von
Hier sind die wichtigsten Ausschnitte aus dem TCP Beispiel, welches auch auf GitHub verfügbar ist:
Client
Server
Ein vollständiges Beispiel über TCP könnt ihr hier finden. Das Projekt ist auf GitHub verfügbar: github.com/Alkalinee/DataTransferProtocol
Vielleicht kann's ja jemand gebrauchen
WCF war mir immer zu umständlich und ich hatte zu wenig Kontrolle, außerdem sind Events extrem kompliziert zu implementieren und ein gescheites Authentifizierungssystem wollte auch nicht klappen, also habe ich diese kleine Bibliothek geschrieben, welche über egal welche Verbindung Methoden und Funktionen mit oder ohne Parameter aufrufen kann. Das ganze ist sehr einfach zu benutzen:
Auf der Serverseite habt ihr folgenden Code:
und auf der Client-Seite dann folgenden Code:
Das ist beinah auch schon alles. Jetzt müssen nur noch die einzelnen Punkte miteinander vernetzt werden:
und schon ist es fertig. Es können natürlich nicht nur Strings und andere primitive Datentypen übertragen werden, sondern auch alle Klassen und sogar abstrakte Klassen sind ohne Probleme möglich (die Typen der abstrakten Klassen müssen dann beim Senden und Empfangen angegeben werden, einfach die Überladung von
ExecuteMethod
/ExecuteFunction
, parameters.GetValue
und RegisterMethod
/RegisterFunction
anschauen). Serialisiert wird mit dem Netserializer, welcher eine hohe Performance verspricht. Außerdem werden die Daten mit dem LZF Algorithmus komprimiert.Hier sind die wichtigsten Ausschnitte aus dem TCP Beispiel, welches auch auf GitHub verfügbar ist:
C#-Quellcode
- public class TcpClientTest : IDisposable
- {
- private readonly BinaryReader _binaryReader;
- private readonly BinaryWriter _binaryWriter;
- private readonly NetworkStream _networkStream;
- private readonly Func<byte> _readByteDelegate;
- private readonly TcpClient _tcpClient;
- private readonly object _writeLock = new object();
- private bool _isDisposed;
- private TcpClientTest(TcpClient tcpClient)
- {
- _tcpClient = tcpClient;
- _networkStream = tcpClient.GetStream();
- _binaryWriter = new BinaryWriter(_networkStream);
- _binaryReader = new BinaryReader(_networkStream);
- DataTransferProtocolFactory = new DtpFactory(SendData);
- _readByteDelegate += _binaryReader.ReadByte;
- _readByteDelegate.BeginInvoke(EndRead, null);
- }
- public DtpFactory DataTransferProtocolFactory { get; }
- public void Dispose()
- {
- if (_isDisposed)
- return;
- _isDisposed = true;
- using (_binaryReader)
- using (_binaryWriter)
- using (_networkStream)
- _tcpClient.Close();
- Disconnected?.Invoke(this, EventArgs.Empty);
- }
- public event EventHandler Disconnected;
- private void SendData(byte[] data)
- {
- if (_isDisposed)
- return;
- lock (_writeLock)
- {
- _binaryWriter.Write((byte) ClientPackageToken.DataTransferProtocol);
- _binaryWriter.Write(data.Length);
- _binaryWriter.Write(data);
- }
- }
- private void EndRead(IAsyncResult asyncResult)
- {
- try
- {
- var parameter = _readByteDelegate.EndInvoke(asyncResult);
- var size = _binaryReader.ReadInt32();
- var bytes = _binaryReader.ReadBytes(size);
- switch ((ServerPackageToken) parameter)
- {
- case ServerPackageToken.DataTransferProtocolResponse:
- DataTransferProtocolFactory.Receive(bytes);
- break;
- }
- _readByteDelegate.BeginInvoke(EndRead, null);
- }
- catch (Exception)
- {
- Dispose();
- }
- }
- }
C#-Quellcode
- private void showMessageBoxButton_Click(object sender, EventArgs e)
- {
- _tcpClientTest.DataTransferProtocolFactory.ExecuteMethod("ShowMessageBox", showMessageBoxTextBox.Text ?? "");
- }
- private void getServerInformationButton_Click(object sender, EventArgs e)
- {
- var information =
- _tcpClientTest.DataTransferProtocolFactory.ExecuteFunction<ServerInformation>("GetServerInformation");
- MessageBox.Show(
- $"MachineName: {information.MachineName}\r\nUserName: {information.UserName}\r\nOperatingSystem: {information.OperatingSystem}\r\nPageSize: {information.PageSize}");
- }
C#-Quellcode
- public class TestClient : IDisposable
- {
- private readonly BinaryReader _binaryReader;
- private readonly BinaryWriter _binaryWriter;
- private readonly NetworkStream _networkStream;
- private readonly Func<byte> _readByteDelegate;
- private readonly TcpClient _tcpClient;
- private bool _isDisposed;
- private readonly DtpProcessor _dtpProcessor;
- private readonly object _sendLock = new object();
- public TestClient(TcpClient tcpClient)
- {
- _tcpClient = tcpClient;
- _networkStream = tcpClient.GetStream();
- _binaryWriter = new BinaryWriter(_networkStream);
- _binaryReader = new BinaryReader(_networkStream);
- _dtpProcessor = new DtpProcessor();
- InitializeDataTransferProtocol();
- _readByteDelegate += _binaryReader.ReadByte;
- _readByteDelegate.BeginInvoke(EndRead, null);
- }
- public void Dispose()
- {
- if (_isDisposed)
- return;
- _isDisposed = true;
- using (_binaryReader)
- using (_binaryWriter)
- using (_networkStream)
- _tcpClient.Close();
- Disconnected?.Invoke(this, EventArgs.Empty);
- }
- public event EventHandler Disconnected;
- private void InitializeDataTransferProtocol()
- {
- _dtpProcessor.RegisterMethod("ShowMessageBox", parameters => MessageBox.Show(parameters.GetString(0)));
- _dtpProcessor.RegisterFunction("GetServerInformation",
- parameters =>
- new ServerInformation
- {
- MachineName = Environment.MachineName,
- OperatingSystem = Environment.OSVersion.ToString(),
- PageSize = Environment.SystemPageSize,
- UserName = Environment.UserName
- });
- }
- private void EndRead(IAsyncResult asyncResult)
- {
- try
- {
- var parameter = _readByteDelegate.EndInvoke(asyncResult);
- var size = _binaryReader.ReadInt32();
- var bytes = _binaryReader.ReadBytes(size);
- switch ((ClientPackageToken) parameter)
- {
- case ClientPackageToken.DataTransferProtocol:
- var result = _dtpProcessor.Receive(bytes);
- lock (_sendLock)
- {
- _binaryWriter.Write((byte) ServerPackageToken.DataTransferProtocolResponse);
- _binaryWriter.Write(result.Length);
- _binaryWriter.Write(result);
- }
- break;
- }
- _readByteDelegate.BeginInvoke(EndRead, null);
- }
- catch (Exception)
- {
- Dispose();
- }
- }
- }
Ein vollständiges Beispiel über TCP könnt ihr hier finden. Das Projekt ist auf GitHub verfügbar: github.com/Alkalinee/DataTransferProtocol
Vielleicht kann's ja jemand gebrauchen