<commit_before>## Build status
**Master Branch**

[![Build Status](https://travis-ci.org/Jallah/EasyProt.svg?branch=master)](https://travis-ci.org/Jallah/EasyProt)
[![Build status](https://ci.appveyor.com/api/projects/status/cyi4mev19l12jyya?svg=true)](https://ci.appveyor.com/project/Jallah/easyprot)

## Description
EasyProt is a very lightwight Framwork for implementing your own Client-Server-Based Protocol. Usually you just have to define your messages by implementing the `IProtMessage ` interface. The communication between the Clients and the Sever runs asynchronus.

## Usage
There are much cool things you can do to create your own Protocol. EasyProt is written in F# but you can write your Implementation in every .NET Language even in VB .NET (don't take it too serious VB-Lovers :P). You can define a Pipeline (see below) for handling outgoing messages. You can even write your own implementation for the Client-Server-Communication by implementing the ``IProtClient`` and/or ``IProtServer`` interface. The default implementation uses a simple ``TcpClient`` with an unencrypted stream. But you can write your own implementation wich uses a ``SslStream``.

**IPipelineMember**

This interface just consits of one method:
``` csharp
// C# string Proceed(string message)
abstract member Proceed : string -> string
```
Let's look at two very simple implementations:
``` csharp
let member1 = 
    { new IPipelineMember with
          member this.Proceed input = input + "XX" }

let member2 = 
    { new IPipelineMember with
          member this.Proceed input = "XX" + input }
```
The result of this pipeline will be a string with leading and trailing **"XX"** (see screenshot below). Some real world example could be a member which logs the message somewhere. Or a member could act as an insult filter wich detects bad words and converts it into **$%+!?#&** or whatever.Some other implementation could convert from one format to another e.g. from XML to Json. It's a very flexible way to do some stuff with your outgoing messages with no limits being set to your imagination :).

**IProtMessage**
``` csharp
// C# bool Validate(string message)
abstract member Validate : message:string -> bool
// C# Task HandleMessageAsync(string message)
abstract member HandleMessageAsync : message:string -> Async<unit>
```
The ``Validate()`` method ist responsible to determine the message. Let's look at a very simple implementation:
``` csharp
let msg1 = 
    { new IProtMessage with
          member this.Validate message = message.[0] = '1'
          member this.HandleMessageAsync message = async { System.Console.WriteLine("msg1: " + message) } }
```
So every time when the first sign of an incoming message is a **_1_** the Client or Server (depending on where you register your messages) knows wich ``HandleMessageAsync()`` implementation or Pipeline should be called. This member is the counterpart to the Pipeline.

## RuntimeManager

After defining your messages and pipelines you should use the ``RuntimeManager`` as follows:

``` csharp
let rntMngr = new EasyProt.Runtime.RuntimeManager()
rntMngr.RegisterMessage(member1 :: member2 :: [], msg1) |> ignore
rntMngr.RegisterMessage(msg2) |> ignore // use default pipeline -> input == output
rntMngr.RegisterMessage(msg3) |> ignore
```
After registering your messages you can let the RuntimeManager Create the Client and/or Server for you:
``` csharp
// ...
let client = rntMngr.GetProtClient()
```

``` csharp
// ...
let server = rntMngr.GetProtServer()
```
The ``RuntimeManager``-ctor is overloaded so you can pass your own ``IProtClient`` and ``IProtServer`` implemenation. Otherwise the default ones will be used (EasyProt/src/EasyProt.Runtime/Runtime.fs).

You can find this samples in EasyProt/tests/EasyProt.ConsoleTest/Program.fs (Client) and  EasyProt/tests/EasyProt.TestServer/Program.fs (Server). Following you will see a screenshot of the including test client (left side) and a test server (right side):

![alt tag](https://github.com/Jallah/EasyProt/blob/master/docs/files/img/ClientServer.jpg)

Some more instructions will follow soon ...

## TODO
- Comments in EasyProt.Runtime.RuntimeManager(.fs)
- Complete Readme

## ISSUES
- FAKE does not support NUNIT >=3: https://github.com/fsharp/FAKE/issues/1010




  <commit_msg>Saved README.md with Dillinger.io<commit_after>## Build status
**Master Branch**

[![Build Status](https://travis-ci.org/Jallah/EasyProt.svg?branch=master)](https://travis-ci.org/Jallah/EasyProt)
[![Build status](https://ci.appveyor.com/api/projects/status/cyi4mev19l12jyya?svg=true)](https://ci.appveyor.com/project/Jallah/easyprot)

## Description
EasyProt is a very lightwight Framwork for implementing your own Client-Server-Based Protocol. Usually you just have to define your messages by implementing the `IProtMessage ` interface. The communication between the Clients and the Sever runs asynchronus.

## Usage
There are much cool things you can do to create your own Protocol. EasyProt is written in F# but you can write your Implementation in every .NET Language even in VB .NET (don't take it too serious VB-Lovers :P). You can define a Pipeline (see below) for handling outgoing messages. You can even write your own implementation for the Client-Server-Communication by implementing the ``IProtClient`` and/or ``IProtServer`` interface. The default implementation uses a simple ``TcpClient`` with an unencrypted stream. But you can write your own implementation wich uses a ``SslStream``.

**IPipelineMember**

This interface just consits of one method:
``` csharp
// C# string Proceed(string message)
abstract member Proceed : string -> string
```
Let's look at two very simple implementations:
``` csharp
let member1 = 
    { new IPipelineMember with
          member this.Proceed input = input + "XX" }

let member2 = 
    { new IPipelineMember with
          member this.Proceed input = "XX" + input }
```
The result of this pipeline will be a string with leading and trailing **"XX"** (see screenshot below). Some real world example could be a member which logs the message somewhere. Or a member could act as an insult filter wich detects bad words and converts it into **$%+!?#&** or whatever.Some other implementation could convert from one format to another e.g. from XML to Json. It's a very flexible way to do some stuff with your outgoing messages with no limits being set to your imagination :).

**IProtMessage**
``` csharp
// C# bool Validate(string message)
abstract member Validate : message:string -> bool
// C# Task HandleMessageAsync(string message)
abstract member HandleMessageAsync : message:string -> Async<unit>
```
The ``Validate()`` method ist responsible to determine the message. Let's look at a very simple implementation:
``` csharp
let msg1 = 
    { new IProtMessage with
          member this.Validate message = message.[0] = '1'
          member this.HandleMessageAsync message = async { System.Console.WriteLine("msg1: " + message) } }
```
So every time when the first sign of an incoming message is a **_1_** the Client or Server (depending on where you register your messages) knows wich ``HandleMessageAsync()`` implementation or Pipeline should be called. This member is the counterpart to the Pipeline.

## RuntimeManager

After defining your messages and pipelines you should use the ``RuntimeManager`` as follows:

``` csharp
let rntMngr = new EasyProt.Runtime.RuntimeManager()
rntMngr.RegisterMessage(member1 :: member2 :: [], msg1) |> ignore
rntMngr.RegisterMessage(msg2) |> ignore // use default pipeline -> input == output
rntMngr.RegisterMessage(msg3) |> ignore
```
After registering your messages you can let the RuntimeManager Create the Client and/or Server for you:
``` csharp
// ...
let client = rntMngr.GetProtClient()
```

``` csharp
// ...
let server = rntMngr.GetProtServer()
```
The ``RuntimeManager``-ctor is overloaded so you can pass your own ``IProtClient`` and ``IProtServer`` implemenation. Otherwise the default ones will be used (EasyProt/src/EasyProt.Runtime/Runtime.fs).

You can find this samples in EasyProt/tests/EasyProt.ConsoleTest/Program.fs (Client) and  EasyProt/tests/EasyProt.TestServer/Program.fs (Server). Following you will see a screenshot of the including test client (left side) and test server (right side):

![alt tag](https://github.com/Jallah/EasyProt/blob/master/docs/files/img/ClientServer.jpg)

Some more instructions will follow soon ...

## TODO
- Comments in EasyProt.Runtime.RuntimeManager(.fs)
- Complete Readme

## ISSUES
- FAKE does not support NUNIT >=3: https://github.com/fsharp/FAKE/issues/1010




  
{'fraction_non_alphanumeric': 0.09941927990708478, 'fraction_numerical': 0.005110336817653891, 'mean_word_length': 4.516335682254965, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1129648', 'n_tokens_mistral': 2481, 'n_tokens_neox': 2306, 'n_words': 982}