Skip to content
This repository has been archived by the owner on Dec 20, 2019. It is now read-only.

Commit

Permalink
Enhancing samples, restorign raw messaging support, bug fixing.
Browse files Browse the repository at this point in the history
  • Loading branch information
dajuric committed Dec 29, 2017
1 parent 42b715f commit 2cbca7d
Show file tree
Hide file tree
Showing 18 changed files with 235 additions and 39 deletions.
2 changes: 0 additions & 2 deletions Samples/AspRpc/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using System;
using System.IO;
using System.Net.WebSockets;
using WebSocketRPC;

namespace AspRpc
Expand Down
File renamed without changes.
14 changes: 8 additions & 6 deletions Samples/ClientJs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Threading.Tasks;
using WebSocketRPC;

namespace TestClientJs
namespace RawMsgJs
{
/// <summary>
/// Remote API.
Expand Down Expand Up @@ -43,22 +43,24 @@ public async Task<int> LongRunningTask(int a, int b)

class Program
{
//if access denied execute: "netsh http delete urlacl url=http://+:8001/"
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
//open Index.html to run the client
static void Main(string[] args)
{
//generate js code
File.WriteAllText($"./Site/{nameof(LocalAPI)}.js", RPCJs.GenerateCallerWithDoc<LocalAPI>());

//start server and bind its local and remote API
var cts = new CancellationTokenSource();
var s = Server.ListenAsync("http://localhost:8005/", cts.Token, (c, ws) =>
var s = Server.ListenAsync("http://localhost:8001/", cts.Token, (c, ws) =>
{
c.Bind<LocalAPI, IRemoteAPI>(new LocalAPI());
c.BindTimeout(TimeSpan.FromSeconds(1)); //close connection if no response after X seconds
//c.BindTimeout(TimeSpan.FromSeconds(1)); //close connection if there is no incommming message after X seconds

c.OnOpen += async () => await c.SendAsync("Hello from server using WebSocketRPC", RPCSettings.Encoding);
});

Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(TestClientJs));
Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(RawMsgJs));
Console.ReadLine();
cts.Cancel();
s.Wait();
Expand Down
3 changes: 2 additions & 1 deletion Samples/ClientJs/Site/Index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
}

//init API
var api = new LocalAPI("ws://localhost:8005");
var api = new LocalAPI("ws://localhost:8001");

//implement the interface
api.writeProgress = function (p)
Expand All @@ -34,6 +34,7 @@
document.getElementById("result").innerHTML = "Result: " + JSON.stringify(r, null, "\t");
}

api.onOtherMessage = writeMsg;
api.connect(() => execAPI(api), err => writeMsg(err, 'red'), msg => writeMsg(msg));
</script>

Expand Down
6 changes: 3 additions & 3 deletions Samples/MultiService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Threading;
using WebSocketRPC;

namespace ClientJsMultiService
namespace MultiService
{
/// <summary>
/// Numeric service providing operations on numbers.
Expand Down Expand Up @@ -41,7 +41,7 @@ public string Add(string a, string b)

class Program
{
//if access denied execute: "netsh http delete urlacl url=http://+:8001/"
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
//open Index.html to run the client
static void Main(string[] args)
{
Expand All @@ -65,7 +65,7 @@ static void Main(string[] args)
})
.Wait(0);

Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(ClientJsMultiService));
Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(MultiService));
Console.ReadLine();
cts.Cancel();
}
Expand Down
40 changes: 32 additions & 8 deletions Samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,37 @@ Samples

The recommendation is to run samples in the following order (from the more simple ones to more complex ones):

1. ServerClientSample
2. ServerClientJs
3. MultiService
4. Serialization
5. AspRpc
1. **RawMsgJs**
Javascript client and C# server.
Sending/receiving raw text mesages.
*Server is receiving messages form a client and sends back altered messages.*

**Remarks**
+ If a sample contains JavaScript client, the additional step is to open the included Index.html.
+ Samples that contain multiple executables have 'Run.bat' for one-click run.
2. **ServerClientSample/++**
C# client and server.
Two way RPC: .NET <-> .NET.
*Server is executing long running task on the client's request and sending progress notifications to to client.*

3. **ClientJs**
Javascript client and C# server.
Two way RPC: .NET <-> Javascript.
*Server is executing long running task on the client's request and sending progress notifications to to client.
Client's code is autogenerated.*

4. **MultiService**
Javascript client(s) and C# server.
Introduction to multi-services RPC.
*Server has two services: numeric and text services / classes. Two Javascript files for each of the services are autogenerated.*

5. **Serialization**
Javascript client and C# server.
Image serialization example.
*Server has image-processing service which receives an image url and gives processed image back to a Javascript client.*

6. **AspRpc**
Javascript client and C# server.
ASP.NET library integration.
*Server has reporting service initiatted and stopped on the client's request.*

**Remarks**
+ If a sample contains JavaScript client, an additional step requires opening the included *'Index.html'*.
+ Samples that contain multiple executables have *'Run.bat'* for one-click run.
52 changes: 52 additions & 0 deletions Samples/RawMsgJs/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.IO;
using System.Threading;
using WebSocketRPC;

namespace RawMsgJs
{
//Empty class (would contains methods if RPC was used).
class MessagingAPI
{ }

class Program
{
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
//open Index.html to run the client
static void Main(string[] args)
{
//set message limit
RPCSettings.MaxMessageSize = RPCSettings.Encoding.GetMaxByteCount(40);

//generate js code
File.WriteAllText($"./Site/{nameof(MessagingAPI)}.js", RPCJs.GenerateCaller<MessagingAPI>());

//start server
var cts = new CancellationTokenSource();
var s = Server.ListenAsync("http://localhost:8001/", cts.Token, (c, ws) =>
{
//set idle timeout
c.BindTimeout(TimeSpan.FromSeconds(30));

c.OnOpen += async () => await c.SendAsync("Hello from server using WebSocketRPC", RPCSettings.Encoding);
c.OnClose += () => Console.WriteLine("Connection closed.");
c.OnError += e => Console.WriteLine("Error: " + e.Message);

c.OnReceive += async (msg, isText) =>
{
var txt = msg.ToString(RPCSettings.Encoding);
Console.WriteLine("Received: " + txt);
await c.SendAsync("Server received: " + txt, RPCSettings.Encoding);

if (txt.ToLower() == "close")
await c.CloseAsync(statusDescription: "Close requested by user.");
};
});

Console.WriteLine("Running: '{0}'. Press [Enter] to exit.", nameof(RawMsgJs));
Console.ReadLine();
cts.Cancel();
s.Wait();
}
}
}
29 changes: 29 additions & 0 deletions Samples/RawMsgJs/RawMsgJs.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net47</TargetFrameworks>
</PropertyGroup>

<PropertyGroup>
<OutputPath>bin\</OutputPath>
<ApplicationIcon />
<OutputType>Exe</OutputType>
<StartupObject />

<DocumentationFile>bin\$(TargetFramework)\ServerClientJs.xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<None Remove="Site\LocalAPI.js" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Source\WebSocketRPC.JS\WebSocketRPC.Js.csproj" />
<ProjectReference Include="..\..\Source\WebsocketRPC.Standalone\WebsocketRPC.Standalone.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Site\Index.html">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
52 changes: 52 additions & 0 deletions Samples/RawMsgJs/Site/Index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<html>
<head>
<script src="MessagingAPI.js"></script>
</head>

<body>
<p>Send/receive messages. Message is sent when the text box loses the focus.</p>
<hr />

<label>Message: </label> <input type="text" id="msg" onblur="onRequest(this)" disabled/>

<p>Responses:</p>
<div id="responses"></div>

<script>
function onConnect()
{
var elem = document.getElementById("msg");
elem.disabled = false;
}

function onRequest(elem)
{
api.send(elem.value);
elem.value = "";
}

function onResponse(msg, color)
{
color = color || 'black';

var p = document.createElement('p');
p.innerHTML = msg;
p.style.color = color;

var lst = document.getElementById("responses");
lst.appendChild(p);
}

function writeMsg(jsonMsg, color)
{
onResponse(JSON.stringify(jsonMsg, null, "\t"), color);
}

//init API
var api = new MessagingAPI("ws://localhost:8001");
api.onOtherMessage = onResponse;
api.connect(onConnect, err => writeMsg(err, 'red'), msg => writeMsg(msg, 'green')); //onConnect, onError, onClose
</script>

</body>
</html>
11 changes: 6 additions & 5 deletions Samples/Serialization/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using WebSocketRPC;
using System.Runtime.CompilerServices;

namespace ServerClientJsSerialization
namespace Serialization
{
class JpgBase64Converter : JsonConverter
{
Expand Down Expand Up @@ -55,7 +55,7 @@ class ImageProcessingAPI

Bgr<byte>[,] image = null;
try { image = imgUrl.GetBytes().DecodeAsColorImage(); }
catch(Exception ex) { throw new Exception("The specified url does not point to a valid image."); }
catch(Exception ex) { throw new Exception("The specified url does not point to a valid image.", ex); }

image.Apply(c => swapChannels(c, order), inPlace: true);
return image;
Expand All @@ -71,7 +71,7 @@ unsafe Bgr<byte> swapChannels(Bgr<byte> c, int[] order)

class Program
{
//if access denied execute: "cmd"
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
//open Index.html to run the client
static void Main(string[] args)
{
Expand All @@ -86,8 +86,9 @@ static void Main(string[] args)
//start server and bind its local and remote API
var cts = new CancellationTokenSource();
Server.ListenAsync("http://localhost:8001/", cts.Token, (c, ws) => c.Bind(new ImageProcessingAPI())).Wait();

Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(ServerClientJsSerialization));


Console.Write("Running: '{0}'. Press [Enter] to exit.", nameof(Serialization));
Console.ReadLine();
cts.Cancel();
}
Expand Down
2 changes: 1 addition & 1 deletion Samples/ServerClientSample/Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void WriteProgress(float progress)

public class Program
{
//if access denied execute: "netsh http delete urlacl url=http://+:8001/"
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
static void Main(string[] args)
{
//Debug.Listeners.Add(new TextWriterTraceListener(Console.Out));
Expand Down
2 changes: 1 addition & 1 deletion Samples/ServerClientSample/Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public async Task<int> LongRunningTask(int a, int b)

public class Program
{
//if access denied execute: "netsh http delete urlacl url=http://+:8001/"
//if access denied execute: "netsh http delete urlacl url=http://+:8001/" (delete for 'ocalhost', add for public address)
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Red;
Expand Down
16 changes: 15 additions & 1 deletion Source/WebSocketRPC.Base/RPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace WebSocketRPC
Expand Down Expand Up @@ -235,8 +234,12 @@ public static async Task<TResult[]> CallAsync<TInterface, TResult>(this IEnumera

#endregion


#region Misc

/// <summary>
/// Gets the connection count.
/// </summary>
public static int ConnectionCount
{
get
Expand All @@ -248,6 +251,17 @@ public static int ConnectionCount
}
}

/// <summary>
/// Gets whether the data contain RPC message or not.
/// </summary>
/// <param name="data">Received data.</param>
/// <returns>True if the data contain RPC message, false otherwise.</returns>
public static bool IsRpcMessage(this ArraySegment<byte> data)
{
var str = data.ToString(RPCSettings.Encoding);
return !Request.FromJson(str).IsEmpty || !Response.FromJson(str).IsEmpty;
}

#endregion
}
}
2 changes: 1 addition & 1 deletion Source/WebSocketRPC.Base/RPCSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static void AddConverter(JsonConverter converter)
}

/// <summary>
/// Gets or sets the maximum message size [1..inf].
/// Gets or sets the maximum message size in bytes [1..Int32.MaxValue].
/// </summary>
public static int MaxMessageSize
{
Expand Down
1 change: 0 additions & 1 deletion Source/WebSocketRPC.JS/Components/JsCallerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public static (string, MethodInfo[]) GetMethods<T>(params Expression<Action<T>>[
var methodList = objType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

var overloadedMethodNames = methodList.GroupBy(x => x.Name)
.DefaultIfEmpty()
.Where(x => x.Count() > 1)
.Select(x => x.Key);

Expand Down
Loading

0 comments on commit 2cbca7d

Please sign in to comment.