<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Platformability &#187; c#</title>
	<atom:link href="http://blog.caplin.com/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caplin.com</link>
	<description>SWIMMING WITH TECHNOLOGY</description>
	<lastBuildDate>Sun, 29 Aug 2010 11:55:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Streamlink for Silverlight for Mobile</title>
		<link>http://blog.caplin.com/2009/08/04/streamlink-for-silverlight-for-mobile/</link>
		<comments>http://blog.caplin.com/2009/08/04/streamlink-for-silverlight-for-mobile/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 16:10:16 +0000</pubDate>
		<dc:creator>Phil Leggetter</dc:creator>
				<category><![CDATA[Mobile]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Comet]]></category>
		<category><![CDATA[Financial Ajax]]></category>
		<category><![CDATA[Real-time web]]></category>
		<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[StreamLink]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[Windows Mobile]]></category>

		<guid isPermaLink="false">http://blog.caplin.com/?p=331</guid>
		<description><![CDATA[With the recent release of Caplin&#8217;s Streamlink for Silverlight it&#8217;s exciting to find out that Microsoft plan to release a Silverlight for Mobile devices. The goal of Silverlight is to provide a consistent experience across desktop and mobile phones. Developers will be able to easily optimize Silverlight applications for mobile form factors or run existing [...]]]></description>
			<content:encoded><![CDATA[<p>With the recent release of Caplin&#8217;s Streamlink for Silverlight it&#8217;s exciting to find out that Microsoft plan to release a <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3NpbHZlcmxpZ2h0Lm5ldC9sZWFybi9tb2JpbGUuYXNweA==">Silverlight for Mobile devices</a>.</p>
<blockquote cite="http://silverlight.net/learn/mobile.aspx"><p>The goal of Silverlight is to provide a consistent experience across desktop and mobile phones. Developers will be able to easily optimize Silverlight applications for mobile form factors or run existing Silverlight applications on mobile phones.</p></blockquote>
<p>The great thing about this release is that any existing Silverlight applications should work on any mobile device with Silverlight installed. The question about this is that if you design a user interface for a desktop browser how will it fit on a windows mobile browser? Well, Microsoft plan to give developers the ability to &#8220;optimize Silverlight applications for mobile form factors&#8221; which sounds like they will give us a way of dealing with the obvious UI differences between desktop and mobile platforms, as well as the underlying runtime issues.</p>
<p>We&#8217;ve already blogged about what impact <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuY2FwbGluLmNvbS8yMDA5LzA2LzA5L3NpbHZlcmxpZ2h0LWZvci1zaW5nbGUtZGVhbGVyLXBvcnRhbHMv">Silverlight may have on single dealer portals</a>. I&#8217;m really excited to see what developers can do using StreamLink for Silverlight to enable the <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2Jsb2cuY2FwbGluLmNvbS8yMDA5LzA0LzIwL3doYXQtaXMtdGhlLXJlYWwtdGltZS13ZWIv">real-time web</a> on a windows mobile device. What opportunities might Streamlink for Silverlight Mobile enable?</p>
<div class="wp-caption alignnone" style="width: 290px"><img alt="Silverlight for Mobile" src="http://i16.photobucket.com/albums/b12/al_oasis1/microsoft_silverlight.jpg" title="Microsoft Silverlight" width="280" height="312" /><p class="wp-caption-text">Silverlight for Mobile</p></div>
<p>Read the <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3NpbHZlcmxpZ2h0Lm5ldC9sZWFybi9tb2JpbGUuYXNweA==">Silverlight for Mobile FAQ</a> for more information.</p>
 <img src="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=331" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.caplin.com/2009/08/04/streamlink-for-silverlight-for-mobile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting realtime data into Excel</title>
		<link>http://blog.caplin.com/2009/06/30/getting-realtime-data-into-excel/</link>
		<comments>http://blog.caplin.com/2009/06/30/getting-realtime-data-into-excel/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 17:00:54 +0000</pubDate>
		<dc:creator>dom</dc:creator>
				<category><![CDATA[Real-time web]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[RTD]]></category>
		<category><![CDATA[StreamLink]]></category>
		<category><![CDATA[StreamLink.NET]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://blog.caplin.com/?p=261</guid>
		<description><![CDATA[Starting with Excel 2002, Microsoft have included the RTD interface which allows Excel to poll for data. Polling seems to be a much more efficient way of getting data into Excel than the classic approach which is pushing &#8211; it&#8217;s not uncommon to find yourself pushing when Excel isn&#8217;t ready which results in lockups, inconstitencies [...]]]></description>
			<content:encoded><![CDATA[<p>Starting with Excel 2002, Microsoft have included the <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21pY3Jvc29mdC5vZmZpY2UuaW50ZXJvcC5leGNlbC5ydGQob2ZmaWNlLjExKS5hc3B4">RTD interface</a> which allows Excel to poll for data. Polling seems to be a much more efficient way of getting data into Excel than the classic approach which is pushing &#8211; it&#8217;s not uncommon to find yourself pushing when Excel isn&#8217;t ready which results in lockups, inconstitencies and other undesirable effects.</p>
<p>The RTD interface is small (6 methods) and Kenny Kerr has a great series of articles about RTD on his <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2h0dHA6Ly93ZWJsb2dzLmFzcC5uZXQva2VubnlrZXJyL2FyY2hpdmUvMjAwOC8xMS8xMy9SdGQzLmFzcHg=">blog</a> so I won&#8217;t repeat that information here and instead concentrate on integration to StreamLink.NET and pulling in real time data from a Caplin platform deployment.</p>
<p>The following walkthrough is a short example of how to do this, there&#8217;s no error checking, logging and certainly the example is nowhere near production quality, however it does demonstrate that linking up Excel and data from the Liberator is straightforward.</p>
<p><span id="more-261"></span></p>
<p><strong>ServerStart</strong> is the entry point and in here we can instantiate StreamLink.NET and setup a map between the RTD topic ids and the Subject/Field information.</p>
<pre name="code" class="c#">    public int ServerStart(IRTDUpdateEvent callback)
    {
        sl = new StreamLinkInterop();
        m_callback = callback;
        m_timer = new Timer();
        m_timer.Tick += new EventHandler(TimerEventHandler);
        m_timer.Interval = 1000;
        m_topics = new Dictionary&lt;int, KeyValuePair&lt;string,string&gt;&gt;();
        return 1;
    }</pre>
<p>The <strong>ConnectData</strong> method validates the arguments passed through and then attempts to subscribe to the data:</p>
<pre name="code" class="c#">public object ConnectData(int topicId,
                              ref Array strings,
                              ref bool newValues)
    {
        if (2 != strings.Length)
        {
            return "Subject and field is required";
        }

        string subject = strings.GetValue(0).ToString();
        string field = strings.GetValue(1).ToString();

        m_topics[topicId] = new KeyValuePair(subject, field);
        m_timer.Start();
        sl.Subscribe(subject, field);
        return "NO_DATA_YET";
    }</pre>
<p>And <strong>DisconnectData</strong> will unsubscribe:</p>
<pre  name="code" class="c#" >    public void DisconnectData(int topicId)
    {
        KeyValuePair pair = m_topics[topicId];

        sl.Unsubscribe(pair.Key, pair.Value);
        m_topics.Remove(topicId);
    }</pre>
<p><strong>RefreshData</strong> will retrieve the current image for the subscribed data:</p>
<pre name="code" class="c#">    public Array RefreshData(ref int topicCount)
    {
        object[,] data = new object[2, m_topics.Count];

        int index = 0;

        foreach (int topicId in m_topics.Keys)
        {
            data[0, index] = topicId;
            KeyValuePair pair = m_topics[topicId];
            data[1, index] = sl.GetData(pair.Key, pair.Value);

            ++index;
        }

        topicCount = m_topics.Count;

        m_timer.Start();
        return data;
    }</pre>
<p>Because Excel polls for the data we&#8217;ve got to have a cache within our RTD server so that data is available when Excel calls in, for the purposes of this exercise we&#8217;re only considering Record data without market depth or history so our cache can be really simple:</p>
<pre name="code"  class="c#">    public class RecordType1Cache
    {
        Dictionary fieldMap = new Dictionary();

        public RecordType1Cache()
        {
        }

        public void Update(IRecordEvent evt)
        {
            foreach ( IField field in evt.Fields.Values )
            {
                fieldMap[field.Name] = field.Value;
            }
        }

        public string GetFieldValue(string fieldName)
        {
            if (fieldMap.ContainsKey(fieldName))
            {
                return fieldMap[fieldName];
            }
            return "NO_FIELD_AVAILABLE";
        }
    }</pre>
<p>The only missing part is the <strong>StreamLinkInterop</strong> class which integrates with StreamLink, this needs to implement the public methods we saw earlier: <strong>Subscribe</strong>, <strong>Unsubscribe</strong> and <strong>GetData</strong> as well as the <strong>IRecordSubscriptionListener</strong> interface from StreamLink.NET since we want to receive record updates. When an update is received we put it into our cache and return immediately.</p>
<p>There&#8217;s a couple of maps which allows finding the <strong>RecordType1Cache</strong> object from both the StreamLink side (using the <strong>IRecordSubscription</strong> as the key) and from the RTD side (using a subscription name as the key).</p>
<p>The connection to the server is setup in the constructor for code simplification purposes. The servername is hard coded so you&#8217;ll probably need to change it or find a way to configure it if you use this code as a base for your own project.</p>
<pre name="code" class="c#">    public class StreamLinkInterop : IRecordSubscriptionListener
   {
        StreamLink myStreamLink;
        Dictionary cache = new Dictionary();
        Dictionary subscriptionLookup = new Dictionary();

        public StreamLinkInterop()
        {
            IStreamLinkConfiguration config = SimpleConfiguration.CreateType2Connection("liberator", 8080);
            myStreamLink = new StreamLink(config);
            myStreamLink.CredentialsProvider = new PasswordCredentialsProvider("admin", "admin");
            myStreamLink.StreamLinkProvider.Connect();
        }

        public void Terminate()
        {
            myStreamLink.StreamLinkProvider.Disconnect();
        }

        public void Subscribe(string subject, string field)
        {
            string name = subject + ";" + field;

            IRecordSubscriptionParameters rparams = myStreamLink.StreamLinkProvider.ParametersFactory.CreateRecordSubscriptionParameters(new string[] { field } );
            ISubscription sub = myStreamLink.StreamLinkProvider.CreateRecordSubscription(this, subject , rparams);

            cache[sub] = new RecordType1Cache();
            subscriptionLookup[name] = sub;
            sub.Subscribe();
        }

        public void Unsubscribe(string subject, string field)
        {
            string name = subject + ";" + field;

            if (subscriptionLookup.ContainsKey(name))
            {
                ISubscription sub = subscriptionLookup[name];
                sub.Unsubscribe();
                cache.Remove(sub);
                subscriptionLookup.Remove(name);
            }
        }
       public string GetData(string subject, string field)
        {
            string name = subject + ";" + field;
            if (subscriptionLookup.ContainsKey(name))
            {
                ISubscription sub = subscriptionLookup[name];
                return cache[sub].GetFieldValue(field);
            }
            return "UNKNOWN+SUBJECT";
        }

        #region IRecordSubscriptionListener Members

        public void RecordType2Updated(Caplin.StreamLink.Subscription.ISubscription subscription, IRecordType2Event ev)
        {
        }

        public void RecordType3Updated(Caplin.StreamLink.Subscription.ISubscription subscription, IRecordType3Event ev)
        {
        }

        public void RecordUpdated(Caplin.StreamLink.Subscription.ISubscription subscription, IRecordEvent ev)
        {
            if (cache.ContainsKey(subscription))
            {
                cache[subscription].Update(ev);
            }
        }

        #endregion

        #region ISubscriptionListener Members

        public void SubscriptionErrorReceived(Caplin.StreamLink.Subscription.ISubscription subscription, Caplin.StreamLink.Subscription.ISubscriptionErrorEvent ev)
        {
        }

        public void SubscriptionStatusUpdated(Caplin.StreamLink.Subscription.ISubscription subscription, Caplin.StreamLink.Subscription.ISubscriptionStatusEvent ev)
        {
        }

        #endregion
    }</pre>
<p>To pull data into excel into excel use a formula along the following lines: <code>=RTD("com.caplin.excel",,"/I/MSFT.O", "BID")</code>. The data in the cell will update periodically (by default every 2000ms). This period can be changed using either a registry setting or using VBA, details can be found at <a  href="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2FhMTQwMDYwKG9mZmljZS4xMCkuYXNweCNvZGNfeGxydGRmYXFfaG93Y29uZmlncnRkdGhyb3R0bGU=">MSDN</a>.</p>
 <img src="http://blog.caplin.com/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=261" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://blog.caplin.com/2009/06/30/getting-realtime-data-into-excel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
