Skip to content

Commit

Permalink
Cleaned up directory structure
Browse files Browse the repository at this point in the history
- [Cleanup] Put all the source in a Sources directory, and grouped together the DotNet library
- [Documentation] Updated README to contain more useful information in case somebody lands on that page rather than the website
- [Cleanup] Removed a few TODO's in the DotNet library
  • Loading branch information
floriansegginger committed Nov 18, 2015
1 parent a5f0d32 commit 4397cb5
Show file tree
Hide file tree
Showing 79 changed files with 75 additions and 48 deletions.
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
bin
obj
/*.suo
/WoopsaDemoServer/*.suo
/WoopsaC/Debug
/WoopsaC/DemoServer/Debug
Debug
*.suo
*.suo
*.sdf
*.suo
*.filters
Expand Down
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
# Woopsa
The Woopsa libraries for creating servers and clients
Woopsa is a protocol that's simple, lightweight, free, open-source, web and object-oriented, publish-subscribe, real-time capable and Industry 4.0 ready. It contributes to the revolution of the Internet of Things.

## I just want the freaking library!
Woopsa allows you to share the complete object model of your application in a way that's similar to OPC-UA. It's based on rock-solid foundations such as HTTP and JSON, which makes it work on the web out-of-the-box. Our mission is to get Woopsa on as many platforms as possible. Today, C# and JavaScript implementations exist, but there are much more to come!

**Example JavaScript Client**

```javascript
var woopsa = new WoopsaClient("http://demo.woopsa.org/woopsa", jQuery);
woopsa.read("/Temperature", function(result){
//result = 42
});
```


**Example C# Server**

```csharp
WeatherStation station = new WeatherStation();
WoopsaServer server = new WoopsaServer(station);

station.Temperature = 42;
```

## Getting the library
The latest release is part of the git repository, in the well-named **Release** directory. It contains the .NET and JavaScript versions of the Woopsa library, as well as a few examples to get started!

You can of course also go to the Releases tab of this project, to get version 1.0 here: https://github.com/woopsa-protocol/Woopsa/releases/tag/v1.0

## Getting started
All the information you need is available on www.woopsa.org/get-started
Our [Getting Started](http://www.woopsa.org/get-started/) tutorial allows you to get started quickly with Woopsa. It's really easy and we promise you'll be convinced!

## Building / Making a release
### Windows
Expand Down
Binary file modified Release/DotNet/Woopsa.dll
Binary file not shown.
Binary file modified Release/DotNet/Woopsa.pdb
Binary file not shown.
Binary file modified Release/DotNet/WoopsaDemoClient.exe
Binary file not shown.
Binary file modified Release/DotNet/WoopsaDemoServer.exe
Binary file not shown.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public void Subscribe(string path)
{
if (_subscriptionChannel == null)
{
// TODO: fallback if no subscription service
if (!_hasSubscriptionService.HasValue)
{
// TODO : Check if this is supported on the server
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,8 @@ public WoopsaNotFoundException(string message, Exception innerException)
}
}

// TODO: This used to inherit from WoopsaException
// Inheriting from InvalidOperationException allows this exception
// to be raised in Getters/Setters, such as WoopsaJsonData indexers
[Serializable]
public class WoopsaInvalidOperationException : InvalidOperationException
public class WoopsaInvalidOperationException : WoopsaException
{
public WoopsaInvalidOperationException()
{
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ private void Listen()
{
try
{
// TODO : Make sure the stream is closed every time
// in all cases
TcpClient client = _listener.AcceptTcpClient();
Stream clientStream = client.GetStream();

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,18 @@ public WoopsaJsonData this[string key]
return new WoopsaJsonData(dic[key]);
}
else
throw new WoopsaInvalidOperationException("String indexer is only available on WoopsaJsonData of type Object.");
throw new InvalidOperationException("String indexer is only available on WoopsaJsonData of type Object.");
}
}

// TODO: Existe-t-il un truc plus propre? Si ce n'est pas un
// dictionnaire, on aimerait bien éviter ce genre de propriété
public IEnumerable<string> Keys
{
get
{
if (IsDictionary)
return (_data as Dictionary<string, object>).Keys;
else
throw new WoopsaInvalidOperationException("List of keys is only available on WoopsaJsonData of type Object");
return new string[0];
}
}

Expand All @@ -53,7 +51,7 @@ public WoopsaJsonData this[int key]
return new WoopsaJsonData(arr[key]);
}
else
throw new WoopsaInvalidOperationException("Integer indexer is only available on JsonDataof type Array.");
throw new InvalidOperationException("Integer indexer is only available on JsonDataof type Array.");
}
}

Expand All @@ -64,7 +62,7 @@ public int Length
if (IsArray)
return (_data as object[]).Length;
else
throw new WoopsaInvalidOperationException("Length is only available on WoopsaJsonData of type Array.");
throw new InvalidOperationException("Length is only available on WoopsaJsonData of type Array.");
}
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -271,20 +271,18 @@ private void AddPropertyFromCache(PropertyCache property)

private void AddItemFromCache(ItemCache item)
{
// TODO : Avoid failing silently
try
{
object value = item.PropertyInfo.GetValue(TargetObject);
// If an inner item is null, we ignore it from the Woopsa hierarchy
if (value != null)
new WoopsaObjectAdapter(this, item.PropertyInfo.Name, item.PropertyInfo.GetValue(TargetObject), _visibility, Options);
}
catch (Exception) { } // Property getters that throw exceptions don't play nice. So we fail silently
catch (Exception) { } // Property getters that throw exceptions are not added to the object hierarchy
}

private void AddMethodFromCache(MethodCache method)
{
// TODO : Avoid failing silently
try
{
new WoopsaMethod(this, method.MethodInfo.Name, method.ReturnType, method.WoopsaArguments, (args) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public WoopsaJsonData JsonData
get
{
if (_jsonData == null)
throw new WoopsaInvalidOperationException("JsonData is only available on WoopsaValue of type JsonData");
throw new InvalidOperationException("JsonData is only available on WoopsaValue of type JsonData");
else
return _jsonData;
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ int main(int argc, char argv[]) {
WoopsaUInt16 responseLength;

memset(buffer, 0, sizeof(buffer));
WoopsaInit(&server, "/woopsa/", woopsaEntries);
WoopsaServerInit(&server, "/woopsa/", woopsaEntries);

printf("Woopsa C library v0.1 demo server.\n");

Expand Down Expand Up @@ -120,8 +120,8 @@ int main(int argc, char argv[]) {
break;
}

if (WoopsaCheckRequestFinished(buffer, sizeof(buffer)) != 1) {
//continue;
if (WoopsaCheckRequestComplete(buffer, sizeof(buffer)) != 1) {
continue;
}

if (WoopsaHandleRequest(&server, buffer, sizeof(buffer), buffer, sizeof(buffer), &responseLength) >= WOOPSA_SUCCESS) {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "woopsa-server.h"
#include <string.h>
#include <stdio.h>

// Thanks microsoft for not supporting snprintf!
#if defined(_MSC_VER) && _MSC_VER < 1900
Expand Down Expand Up @@ -114,7 +115,7 @@ TypesDictionaryEntry * GetTypeEntry(WoopsaType type) {
// Also sets nextHeader to be the start of the next header
// Returns the length of the *current* header, or -1 if this header is empty
// (which means this is the double new-line at the end of HTTP request)
WoopsaInt16 NextHTTPHeader(WoopsaChar8* searchString, WoopsaChar8** nextHeader) {
WoopsaInt16 NextHTTPHeader(const WoopsaChar8* searchString, const WoopsaChar8** nextHeader) {
WoopsaUInt16 i = 0, carriageFound = 0;
while (searchString[i] != '\0') {
if (carriageFound == 1 && searchString[i] == '\n') {
Expand Down Expand Up @@ -180,7 +181,7 @@ WoopsaUInt16 PrepareResponse(
WoopsaUInt16* contentLengthPosition) {
WoopsaUInt16 size = 0;

outputBuffer[0] = NULL;
outputBuffer[0] = '\0';

// HTTP/1.1
size = Append(outputBuffer, HTTP_VERSION_STRING " ", outputBufferLength);
Expand Down Expand Up @@ -232,12 +233,12 @@ WoopsaUInt16 PrepareError(WoopsaChar8* outputBuffer, const WoopsaUInt16 outputBu
// BEGIN PUBLIC WOOPSA IMPLEMENTATION //
///////////////////////////////////////////////////////////////////////////////

void WoopsaInit(WoopsaServer* server, WoopsaChar8* pathPrefix, WoopsaProperty properties[]) {
void WoopsaServerInit(WoopsaServer* server, WoopsaChar8* pathPrefix, WoopsaProperty properties[]) {
server->pathPrefix = pathPrefix;
server->properties = properties;
}

WoopsaUInt8 WoopsaCheckRequestFinished(WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength) {
WoopsaUInt8 WoopsaCheckRequestComplete(WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength) {
if (strstr(inputBuffer, "\r\n\r\n") == 0)
return 0;
else
Expand All @@ -249,14 +250,14 @@ WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBu
WoopsaChar8* woopsaPath = NULL;
//HttpHeader parsedHeader;
WoopsaChar8 numericValueBuffer[MAX_NUMERICAL_VALUE_LENGTH];
WoopsaChar8 oldChar = NULL;
WoopsaChar8 oldChar = '\0';
WoopsaUInt16 i = 0, pos = 0, isPost = 0, contentLengthPosition = 0, contentLength = 0;
WoopsaInt16 headerSize = 0;
WoopsaProperty* woopsaProperty = NULL;
TypesDictionaryEntry* typeEntry = NULL;
WoopsaChar8* buffer = server->buffer;

memset(buffer, NULL, sizeof(WoopsaBuffer));
memset(buffer, 0, sizeof(WoopsaBuffer));

headerSize = NextHTTPHeader(inputBuffer, &header);
if (headerSize == -1)
Expand Down Expand Up @@ -291,7 +292,7 @@ WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBu
woopsaPath = &(buffer[strlen(server->pathPrefix)]);
if (strstr(woopsaPath, VERB_META) == woopsaPath && isPost == 0) {
// Meta request
buffer[0] = NULL;
buffer[0] = '\0';

// TODO : Do something useful with that path
woopsaPath = &(woopsaPath[sizeof(VERB_META)]);
Expand All @@ -307,15 +308,15 @@ WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBu
contentLength += Append(outputBuffer, JSON_PROPERTY_TYPE, outputBufferLength);
contentLength += Append(outputBuffer, typeEntry->string, outputBufferLength);
contentLength += Append(outputBuffer, JSON_PROPERTY_READONLY, outputBufferLength);
contentLength += Append(outputBuffer, (woopsaProperty->readOnly) ? JSON_FALSE : JSON_TRUE, outputBufferLength);
contentLength += Append(outputBuffer, (woopsaProperty->readOnly == 1) ? JSON_TRUE : JSON_FALSE, outputBufferLength);
contentLength += Append(outputBuffer, JSON_PROPERTY_END, outputBufferLength);
if (server->properties[i + 1].name != NULL)
contentLength += Append(outputBuffer, JSON_ARRAY_DELIMITER, outputBufferLength);
}
contentLength += Append(outputBuffer, JSON_ARRAY_END JSON_META_END, outputBufferLength);
} else if (strstr(woopsaPath, VERB_READ) == woopsaPath && isPost == 0) {
// Read request
buffer[0] = NULL;
buffer[0] = '\0';
woopsaPath = &(woopsaPath[sizeof(VERB_READ)]);
if ((woopsaProperty = GetPropertyByNameOrNull(server->properties, woopsaPath)) == NULL) {
*responseLength = PrepareError(outputBuffer, outputBufferLength, HTTP_CODE_NOT_FOUND, HTTP_TEXT_NOT_FOUND);
Expand All @@ -331,7 +332,7 @@ WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBu
|| woopsaProperty->type == WOOPSA_TYPE_RESOURCE_URL
|| woopsaProperty->type == WOOPSA_TYPE_DATE_TIME) {
contentLength += Append(outputBuffer, JSON_STRING_DELIMITER, outputBufferLength);
contentLength += AppendEscape(outputBuffer, woopsaProperty->address, JSON_STRING_DELIMITER_CHAR, JSON_ESCAPE_CHAR, outputBufferLength);
contentLength += AppendEscape(outputBuffer, (WoopsaChar8*)woopsaProperty->address, JSON_STRING_DELIMITER_CHAR, JSON_ESCAPE_CHAR, outputBufferLength);
contentLength += Append(outputBuffer, JSON_STRING_DELIMITER, outputBufferLength);
} else {
snprintf(numericValueBuffer, MAX_NUMERICAL_VALUE_LENGTH, typeEntry->format, *(woopsaProperty->address));
Expand All @@ -343,6 +344,15 @@ WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBu
contentLength += Append(outputBuffer, JSON_VALUE_END, outputBufferLength);
} else if (strstr(woopsaPath, VERB_WRITE) == woopsaPath && isPost == 1) {
// Write request
buffer[0] = '\0';
woopsaPath = &(woopsaPath[sizeof(VERB_READ)]);
if ((woopsaProperty = GetPropertyByNameOrNull(server->properties, woopsaPath)) == NULL) {
*responseLength = PrepareError(outputBuffer, outputBufferLength, HTTP_CODE_NOT_FOUND, HTTP_TEXT_NOT_FOUND);
return WOOPSA_CLIENT_REQUEST_ERROR;
}
typeEntry = GetTypeEntry(woopsaProperty->type);

// Decode POST data
} else {
// Invalid request
*responseLength = PrepareError(outputBuffer, outputBufferLength, HTTP_CODE_NOT_FOUND, HTTP_TEXT_NOT_FOUND);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ extern "C"

// Creates a new Woopsa server using the specified prefix
// and a list of properties to publish
void WoopsaInit(WoopsaServer* server, WoopsaChar8* prefix, WoopsaProperty properties[]);
void WoopsaServerInit(WoopsaServer* server, WoopsaChar8* prefix, WoopsaProperty properties[]);

// Checks if the request contained in inputBuffer
// is finished. This is useful in the case where
// data is received in fragments for some reason.
// You should always call this method on your buffer
// before passing it to WoopsaHandleRequest
WoopsaChar8 WoopsaCheckRequestFinished(WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength);
WoopsaUInt8 WoopsaCheckRequestComplete(WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength);

// Parses a request and prepares the reply as well
// Returns:
Expand All @@ -80,7 +80,7 @@ WoopsaChar8 WoopsaCheckRequestFinished(WoopsaChar8* inputBuffer, WoopsaUInt16 i
#define WOOPSA_CLIENT_REQUEST_ERROR 1
#define WOOPSA_OTHER_ERROR 2

WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength, WoopsaChar8* outputBuffer, WoopsaUInt16 outputBufferLength, WoopsaUInt16* responseLength);
WoopsaUInt8 WoopsaHandleRequest(WoopsaServer* server, const WoopsaChar8* inputBuffer, WoopsaUInt16 inputBufferLength, WoopsaChar8* outputBuffer, WoopsaUInt16 outputBufferLength, WoopsaUInt16* responseLength);

#ifdef __cplusplus
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
23 changes: 12 additions & 11 deletions make-release-windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,35 @@ REM Some useful variables
set RELEASE_DIR=Release
set DOT_NET_RELEASE_DIR=DotNet
set DOT_NET_PROJECT_DIR=Woopsa
set DOT_NET_SOURCES_DIR=Sources\DotNet
set DOT_NET_SERVER_EXAMPLE_DIR=WoopsaDemoServer
set DOT_NET_CLIENT_EXAMPLE_DIR=WoopsaDemoClient
set JAVASCRIPT_RELEASE_DIR=JavaScript
set JAVASCRIPT_PROJECT_DIR=WoopsaWeb
set JAVASCRIPT_PROJECT_DIR=Sources\JavaScript

REM .NET Library
if not exist %RELEASE_DIR% mkdir %RELEASE_DIR%
if not exist %RELEASE_DIR%\%DOT_NET_RELEASE_DIR% mkdir %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%
cd %DOT_NET_PROJECT_DIR%
cd %DOT_NET_SOURCES_DIR%\%DOT_NET_PROJECT_DIR%
call build-windows.bat
cd ..
copy %DOT_NET_PROJECT_DIR%\bin\Release\* %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\
cd ..\..\..
copy %DOT_NET_SOURCES_DIR%\%DOT_NET_PROJECT_DIR%\bin\Release\* %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\

REM .NET Demo Server
cd %DOT_NET_SERVER_EXAMPLE_DIR%
cd %DOT_NET_SOURCES_DIR%\%DOT_NET_SERVER_EXAMPLE_DIR%
call build-windows.bat
cd ..
copy %DOT_NET_SERVER_EXAMPLE_DIR%\bin\Release\WoopsaDemoServer.exe %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\
cd ..\..\..
copy %DOT_NET_SOURCES_DIR%\%DOT_NET_SERVER_EXAMPLE_DIR%\bin\Release\WoopsaDemoServer.exe %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\

REM .NET Demo Client
cd %DOT_NET_CLIENT_EXAMPLE_DIR%
cd %DOT_NET_SOURCES_DIR%\%DOT_NET_CLIENT_EXAMPLE_DIR%
call build-windows.bat
cd ..
copy %DOT_NET_CLIENT_EXAMPLE_DIR%\bin\Release\WoopsaDemoClient.exe %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\
cd ..\..\..
copy %DOT_NET_SOURCES_DIR%\%DOT_NET_CLIENT_EXAMPLE_DIR%\bin\Release\WoopsaDemoClient.exe %RELEASE_DIR%\%DOT_NET_RELEASE_DIR%\

REM JavaScript library
if not exist %RELEASE_DIR%\%JAVASCRIPT_RELEASE_DIR% mkdir %RELEASE_DIR%\%JAVASCRIPT_RELEASE_DIR%
cd %JAVASCRIPT_PROJECT_DIR%
call build-windows.bat
cd ..
cd ..\..
copy %JAVASCRIPT_PROJECT_DIR%\dist\* %RELEASE_DIR%\%JAVASCRIPT_RELEASE_DIR%\

0 comments on commit 4397cb5

Please sign in to comment.