<commit_before>---
layout: page
title: Get started
permalink: /get-started/
icon: fa-rocket
classes: get-started col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1
stylesheet: /css/pages/get-started.css
---

<div class="introduction">
    <div class="row">
        <div class="col-xs-12">
            <h1>We're glad you chose Woopsa!</h1>
            <p>Really! We think that once you've learned how to use Woopsa, you won't ever look back. But because our mission is to get Woopsa on as many devices as possible, we need you to tell us what you want to do.</p>
        </div>
    </div>
	<div class="row server-chooser">
        <h3>I want to make a server in:</h3>
        <div class="col-sm-2 col-sm-offset-5">
            <a href="#csharp-server" class="btn btn-lg btn-primary">C# / .NET</a>
        </div>
    </div>
    <h3 class="or">- or -</h3>
	<div class="row client-chooser">    
        <h3>I want to make a client in:</h3>
        <div class="col-sm-3 col-sm-offset-3 col-xs-6">
            <a href="#javascript-client" class="btn btn-lg btn-primary">JavaScript</a>
        </div>
        <div class="col-sm-3 col-xs-6">
            <a href="#csharp-client" class="btn btn-lg btn-primary">C# / .NET</a>
        </div>
    </div>
</div>
<div id="table-of-contents" class="part-block">
	<h1>Table of contents</h1>
	<ul>
		<li>
			<a href="#csharp-server">Using the C# / .NET server</a>
			<ul>
				<li><a href="#csharp-server-introduction">Introduction</a></li>
				<li><a href="#csharp-server-getting-the-assembly-and-using-it">Getting the assembly and using it</a></li>
				<li><a href="#csharp-server-creating-your-first-server">Creating your first server</a></li>
				<li>
					<a href="#csharp-server-going-deeper-with-the-server">Going deeper with the server</a>
					<ul>
						<li><a href="#csharp-server-publishing-only-part-of-your-model">Publishing only part of your model</a></li>
						<li><a href="#csharp-server-working-with-a-complete-hierarchy">Working with a complete hierarchy</a></li>
					</ul>
				</li>
			</ul>
		</li>

		<li>
			<a href="#javascript-client">Using the JavaScript client</a>
			<ul>
				<li><a href="#javascript-client-introduction">Introduction</a></li>
				<li><a href="#javascript-client-getting-the-code">Getting the code</a></li>
				<li><a href="#javascript-client-creating-your-first-client">Creating your first client</a></li>
				<li>
					<a href="#javascript-client-basic-usage">Basic usage</a>
					<ul>
						<li><a href="#javascript-client-exploring-the-object-tree-with-meta">Exploring the object tree with <samp>meta</samp></a></li>
						<li><a href="#javascript-client-reading-a-property-with-read">Reading a property with <samp>read</samp></a></li>
						<li><a href="#javascript-client-writing-to-a-property-with-write">Writing to a property with <samp>write</samp></a></li>
						<li><a href="#javascript-client-calling-a-method-function-with-invoke">Calling a method/function with <samp>invoke</samp></a></li>
					</ul>
				</li>
				<li><a href="#javascript-client-listening-for-value-changes">Listening for value changes</a></li>
			</ul>
		</li>
		<li>
			<a href="#csharp-client">Using the C# / .NET client</a>
			<ul>
				<li><a href="#csharp-client-introduction">Introduction</a></li>
				<li><a href="#csharp-client-getting-the-assembly-and-using-it">Getting the assembly and using it</a></li>
				<li><a href="#csharp-client-creating-your-first-client">Creating your first client</a></li>
				<li>
					<a href="#csharp-client-basic-usage">Basic usage</a>
					<ul>
						<li><a href="#csharp-client-exploring-the-object-tree">Exploring the object tree</a></li>
						<li><a href="#csharp-client-reading-a-property">Reading a property</a></li>
						<li><a href="#csharp-client-writing-to-a-property">Writing to a property</a></li>
						<li><a href="#csharp-client-calling-a-method-function">Calling a method/function</a></li>
					</ul>
				</li>
				<li><a href="#csharp-client-listening-for-value-changes">Listening for value changes</a></li>
				<li><a href="#csharp-client-even-simpler-using-the-dynamic-client">Even simpler: using the dynamic client</a></li>
			</ul>
		</li>
	</ul>
</div>

<div id="csharp-server" class="part-block">
    <h1>Using the C# / .NET server</h1>
    <h2 id="csharp-server-introduction">Introduction</h2>
    <p>Making a Woopsa server is extremely simple and requires just <strong>one</strong> line of code if you're using our reflector! Just give the Woopsa server a class and it will do the rest, automagically!</p>
    <p>The C# / .NET server is included in the <samp>Woopsa</samp> assembly. We created the Woopsa library with Mono in mind, trying to use only the most standard .NET components for maximum compatibility.</p>
    
    <h2 id="csharp-server-getting-the-assembly-and-using-it">Getting the assembly and using it</h2>
    <p>Start off by <a href="/download/">downloading</a> Woopsa and get the Woopsa.dll assembly inside the DotNet folder. Add this assembly as a reference in your Visual Studio project and add the following line to the top of your source file:</p>
    <div class="code">
    {% highlight csharp %}
using Woopsa;
    {% endhighlight %}
    </div>
    <p>That's it! You're now ready to create your server.</p>
    
    <h2 id="csharp-server-creating-your-first-server">Creating your first server</h2>
    <p class="note"><strong>Note:</strong> By default, the Woopsa server resides on <strong>port 80</strong> and has a base path of <samp>/woopsa</samp>, meaning your first server will be available from <samp>http://localhost/woopsa</samp></p>
    <p>To create a simple server, you first need some data to publish to the world. You can set your Woopsa server to handle any C# object, but for example's sake, this is the class we are going to use:</p>
    <div class="code">
    {% highlight csharp %}
public class WeatherStation
{
  public double Temperature { get; private set; }

  public double Sensitivity { get; set; }

  public string GetWeatherAtDate(DateTime date)
  {
    switch (date.DayOfWeek)
    {
      case DayOfWeek.Monday:
        return "cloudy";
      default:
        return "sunny";
    }
  }
}
    {% endhighlight %}
    </div>
	<p>Once you've written your class, you can simply create the new Woopsa server and give it your root object:</p>
    <div class="code">
    {% highlight csharp %}
WeatherStation station = new WeatherStation();
WoopsaServer server = new WoopsaServer(station);
    {% endhighlight %}
    </div>
	<p>That's it! Your Woopsa server is now available on <samp>http://localhost/woopsa</samp>. The server starts in its own thread and uses a thread pool to serve multiple clients at once. This means you really don't have to worry about anything ... just work with your <samp>WeatherStation</samp> like you would with any other object, and Woopsa takes care of everything for you. Including publish/subscribe events!</p>
	<p class="note"><strong>Note:</strong> Woopsa is completely web-based. This means you can see your data simply with a browser! Go on <samp>http://localhost/woopsa/meta/</samp> too see the metadata of your root object, or <samp>http://localhost/woopsa/read/Temperature</samp> to read a piece of data!</p>
	
	<h2 id="csharp-server-going-deeper-with-the-server">Going deeper with the server</h2>
	<h3 id="csharp-server-publishing-only-part-of-your-model">Publishing only part of your model</h3>
	<p>You'll have noticed that the server you just created is not exactly like the one on our demo server (<samp>http://demo.woopsa.org/woopsa</samp>). Most notably, the <samp>ToString()</samp> and <samp>GetHashCode()</samp> methods are published, even though they're not in your class!</p>
	<p>This is because these two methods are common to all classes in .NET, and they're both public. Since by default the Woopsa object reflector (the thing that transforms any class into a <samp>WoopsaObject</samp>) publishes every public property and method, these methods are published.</p>
	<p>If, for any reason, you would not like to publish these methods, or you simply want to choose what to publish, you can! There are two metadata attributes you can use in C# to accomplish this.</p>
	<ul>
		<li><samp>[WoopsaVisible(true)]</samp> Applies to properties, fields and methods. This tells the reflector to publish this item. <strong>Note:</strong> these attributes are ignored if the <samp>[OnlyWoopsaVisible(true)]</samp> isn't present in the class.</li>
		<li><samp>[OnlyWoopsaVisible(true)]</samp> Applies to classes. Just put this attribute on your class and <samp>[WoopsaVisible(true)]</samp> will be taken into account.</li>
	</ul>
	<p>In summary, this is what your new class should look like:</p>
    <div class="code">
    {% highlight csharp %}
[OnlyWoopsaVisible(true)]
public class WeatherStation
{
  [WoopsaVisible(true)]
  public double Temperature { get; private set; }

  [WoopsaVisible(true)]
  public double Sensitivity { get; set; }

  [WoopsaVisible(true)]
  public string GetWeatherAtDate(DateTime date)
  {
    switch (date.DayOfWeek)
    {
      case DayOfWeek.Monday:
        return "cloudy";
      default:
        return "sunny";
    }
  }
}
    {% endhighlight %}
    </div>
	
	<h3 id="csharp-server-working-with-a-complete-hierarchy">Working with a complete hierarchy</h3>
	<p>The reflector works very well, even with nested objects. However, for performance reasons, the object tree is only explored on creation. This means that if you change the embedded objects in your classes, the new data won't be available until you call the <samp>ClearCache</samp> method.</p>
	<p>Here's an example of using embedded objects and where things might go wrong:</p>
    <div class="code"><commit_msg>Updated the Getting Started guide to reflect the new WoopsaVisibility attribute<commit_after>---
layout: page
title: Get started
permalink: /get-started/
icon: fa-rocket
classes: get-started col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1
stylesheet: /css/pages/get-started.css
---

<div class="introduction">
    <div class="row">
        <div class="col-xs-12">
            <h1>We're glad you chose Woopsa!</h1>
            <p>Really! We think that once you've learned how to use Woopsa, you won't ever look back. But because our mission is to get Woopsa on as many devices as possible, we need you to tell us what you want to do.</p>
        </div>
    </div>
	<div class="row server-chooser">
        <h3>I want to make a server in:</h3>
        <div class="col-sm-2 col-sm-offset-5">
            <a href="#csharp-server" class="btn btn-lg btn-primary">C# / .NET</a>
        </div>
    </div>
    <h3 class="or">- or -</h3>
	<div class="row client-chooser">    
        <h3>I want to make a client in:</h3>
        <div class="col-sm-3 col-sm-offset-3 col-xs-6">
            <a href="#javascript-client" class="btn btn-lg btn-primary">JavaScript</a>
        </div>
        <div class="col-sm-3 col-xs-6">
            <a href="#csharp-client" class="btn btn-lg btn-primary">C# / .NET</a>
        </div>
    </div>
</div>
<div id="table-of-contents" class="part-block">
	<h1>Table of contents</h1>
	<ul>
		<li>
			<a href="#csharp-server">Using the C# / .NET server</a>
			<ul>
				<li><a href="#csharp-server-introduction">Introduction</a></li>
				<li><a href="#csharp-server-getting-the-assembly-and-using-it">Getting the assembly and using it</a></li>
				<li><a href="#csharp-server-creating-your-first-server">Creating your first server</a></li>
				<li>
					<a href="#csharp-server-going-deeper-with-the-server">Going deeper with the server</a>
					<ul>
						<li><a href="#csharp-server-publishing-only-part-of-your-model">Publishing only part of your model</a></li>
						<li><a href="#csharp-server-working-with-a-complete-hierarchy">Working with a complete hierarchy</a></li>
					</ul>
				</li>
			</ul>
		</li>

		<li>
			<a href="#javascript-client">Using the JavaScript client</a>
			<ul>
				<li><a href="#javascript-client-introduction">Introduction</a></li>
				<li><a href="#javascript-client-getting-the-code">Getting the code</a></li>
				<li><a href="#javascript-client-creating-your-first-client">Creating your first client</a></li>
				<li>
					<a href="#javascript-client-basic-usage">Basic usage</a>
					<ul>
						<li><a href="#javascript-client-exploring-the-object-tree-with-meta">Exploring the object tree with <samp>meta</samp></a></li>
						<li><a href="#javascript-client-reading-a-property-with-read">Reading a property with <samp>read</samp></a></li>
						<li><a href="#javascript-client-writing-to-a-property-with-write">Writing to a property with <samp>write</samp></a></li>
						<li><a href="#javascript-client-calling-a-method-function-with-invoke">Calling a method/function with <samp>invoke</samp></a></li>
					</ul>
				</li>
				<li><a href="#javascript-client-listening-for-value-changes">Listening for value changes</a></li>
			</ul>
		</li>
		<li>
			<a href="#csharp-client">Using the C# / .NET client</a>
			<ul>
				<li><a href="#csharp-client-introduction">Introduction</a></li>
				<li><a href="#csharp-client-getting-the-assembly-and-using-it">Getting the assembly and using it</a></li>
				<li><a href="#csharp-client-creating-your-first-client">Creating your first client</a></li>
				<li>
					<a href="#csharp-client-basic-usage">Basic usage</a>
					<ul>
						<li><a href="#csharp-client-exploring-the-object-tree">Exploring the object tree</a></li>
						<li><a href="#csharp-client-reading-a-property">Reading a property</a></li>
						<li><a href="#csharp-client-writing-to-a-property">Writing to a property</a></li>
						<li><a href="#csharp-client-calling-a-method-function">Calling a method/function</a></li>
					</ul>
				</li>
				<li><a href="#csharp-client-listening-for-value-changes">Listening for value changes</a></li>
				<li><a href="#csharp-client-even-simpler-using-the-dynamic-client">Even simpler: using the dynamic client</a></li>
			</ul>
		</li>
	</ul>
</div>

<div id="csharp-server" class="part-block">
    <h1>Using the C# / .NET server</h1>
    <h2 id="csharp-server-introduction">Introduction</h2>
    <p>Making a Woopsa server is extremely simple and requires just <strong>one</strong> line of code if you're using our reflector! Just give the Woopsa server a class and it will do the rest, automagically!</p>
    <p>The C# / .NET server is included in the <samp>Woopsa</samp> assembly. We created the Woopsa library with Mono in mind, trying to use only the most standard .NET components for maximum compatibility.</p>
    
    <h2 id="csharp-server-getting-the-assembly-and-using-it">Getting the assembly and using it</h2>
    <p>Start off by <a href="/download/">downloading</a> Woopsa and get the Woopsa.dll assembly inside the DotNet folder. Add this assembly as a reference in your Visual Studio project and add the following line to the top of your source file:</p>
    <div class="code">
    {% highlight csharp %}
using Woopsa;
    {% endhighlight %}
    </div>
    <p>That's it! You're now ready to create your server.</p>
    
    <h2 id="csharp-server-creating-your-first-server">Creating your first server</h2>
    <p class="note"><strong>Note:</strong> By default, the Woopsa server resides on <strong>port 80</strong> and has a base path of <samp>/woopsa</samp>, meaning your first server will be available from <samp>http://localhost/woopsa</samp></p>
    <p>To create a simple server, you first need some data to publish to the world. You can set your Woopsa server to handle any C# object, but for example's sake, this is the class we are going to use:</p>
    <div class="code">
    {% highlight csharp %}
public class WeatherStation
{
  public double Temperature { get; private set; }

  public double Sensitivity { get; set; }

  public string GetWeatherAtDate(DateTime date)
  {
    switch (date.DayOfWeek)
    {
      case DayOfWeek.Monday:
        return "cloudy";
      default:
        return "sunny";
    }
  }
}
    {% endhighlight %}
    </div>
	<p>Once you've written your class, you can simply create the new Woopsa server and give it your root object:</p>
    <div class="code">
    {% highlight csharp %}
WeatherStation station = new WeatherStation();
WoopsaServer server = new WoopsaServer(station);
    {% endhighlight %}
    </div>
	<p>That's it! Your Woopsa server is now available on <samp>http://localhost/woopsa</samp>. The server starts in its own thread and uses a thread pool to serve multiple clients at once. This means you really don't have to worry about anything ... just work with your <samp>WeatherStation</samp> like you would with any other object, and Woopsa takes care of everything for you. Including publish/subscribe events!</p>
	<p class="note"><strong>Note:</strong> Woopsa is completely web-based. This means you can see your data simply with a browser! Go on <samp>http://localhost/woopsa/meta/</samp> too see the metadata of your root object, or <samp>http://localhost/woopsa/read/Temperature</samp> to read a piece of data!</p>
	
	<h2 id="csharp-server-going-deeper-with-the-server">Going deeper with the server</h2>
	<h3 id="csharp-server-publishing-only-part-of-your-model">Publishing only part of your model</h3>
	<p>You'll have noticed that the server you just created is not exactly like the one on our demo server (<samp>http://demo.woopsa.org/woopsa</samp>). Most notably, the <samp>ToString()</samp> and <samp>GetHashCode()</samp> methods are published, even though they're not in your class!</p>
	<p>This is because these two methods are common to all classes in .NET, and they're both public. Since by default the Woopsa object reflector (the thing that transforms any class into a <samp>WoopsaObject</samp>) publishes every public property and method, these methods are published.</p>
	<p>If, for any reason, you would not like to publish these methods, or you simply want to choose what to publish, you can! There are two metadata attributes you can use in C# to accomplish this.</p>
	<ul>
		<li><samp>[WoopsaVisible(true)]</samp> Applies to properties, fields and methods. This tells the reflector to publish this item. <strong>Note:</strong> these attributes are ignored if the <samp>[WoopsaVisbility(WoopsaObjectAdapterVisibility.WoopsaVisible)]</samp> isn't present in the class.</li>
		<li><samp>[WoopsaVisbility(WoopsaObjectAdapterVisibility.WoopsaVisible)]</samp> Applies to classes. Just put this attribute on your class and <samp>[WoopsaVisible(true)]</samp> will be taken into account.</li>
	</ul>
	<p>In summary, this is what your new class should look like:</p>
    <div class="code">
    {% highlight csharp %}
[WoopsaVisbility(WoopsaObjectAdapterVisibility.WoopsaVisible)]
public class WeatherStation
{
  [WoopsaVisible(true)]
  public double Temperature { get; private set; }

  [WoopsaVisible(true)]
  public double Sensitivity { get; set; }

  [WoopsaVisible(true)]
  public string GetWeatherAtDate(DateTime date)
  {
    switch (date.DayOfWeek)
    {
      case DayOfWeek.Monday:
        return "cloudy";
      default:
        return "sunny";
    }
  }
}
    {% endhighlight %}
    </div>
	
	<h3 id="csharp-server-working-with-a-complete-hierarchy">Working with a complete hierarchy</h3>
	<p>The reflector works very well, even with nested objects. However, for performance reasons, the object tree is only explored on creation. This means that if you change the embedded objects in your classes, the new data won't be available until you call the <samp>ClearCache</samp> method.</p>
	<p>Here's an example of using embedded objects and where things might go wrong:</p>
    <div class="code">
{'fraction_non_alphanumeric': 0.14453344217131778, 'fraction_numerical': 0.0041834600275496145, 'mean_word_length': 3.6939655172413794, 'pattern_counts': {'":': 0, '<': 551, '<?xml version=': 0, '>': 551, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6225985', 'n_tokens_mistral': 6843, 'n_tokens_neox': 6216, 'n_words': 1937}