WCF For Remote Robotics Control - WCF Instancing

by Andy 2. October 2008 13:40

WCF really caught my interest when I read that is fully supports both message and transport security; and the netTCP binding also interested me as a high performance option.  I have a basic mobile robot platform with a pan tilt camera and microphone on board and an application allowing me to remote control my robot over the web.  This series will cover some of things I have learned as I build new remote control applications using WCF.

Part 1: Discusses why WCF Instancing is crucial and how I control access to my one serial port connection.

Part 2: Web client using a REST type architecture and jQuery.   This provides a broad reach option for my application and I'll discuss how I can provide access control in this scenario. 

Part 3: Windows application using message security allows me to use two way certificate authentication to control access.

In the past I have used web services and .Net remoting as a way to access the services or resources of my mobile robot.  ws-* was not around then so neither of these options provides any security (I guess I could have used web services over SSL and pass a secret as a parameter in each call) which is a BIG problem given that users can drive the mobile robot around my house and take a good look around with the camera.  Hence I have never left this service available through my firewall.

My robot uses a serial port to communicate to an onboard controller (Brainstem) that controls the motors, servos, and sensors.  WCF provides the ServiceBehaviorAttribute.InstanceContextMode Property which can be set to:

  • PerSession - A new InstanceContext object is created for each session.
  • PerCall - A new InstanceContext object is created prior to and recycled subsequent to each call. If the channel does not create a session this value behaves as if it were PerCall.
  • Single - Only one InstanceContext object is used for all incoming calls and is not recycled subsequent to the calls. If a service object does not exist, one is created.

I only want to open the serial port once when the service starts and keep using that for all future calls so I decorate my service class with the following:

   1:  [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
   2:  public class SimpleDriverService : ISimpleDriver
   3:  {
   4:      private RemoteCommander commander = RemoteCommander.Instance;
   5:  }

When the service is started I create my serial port object and open it on line 4.  The commander object which connects to the serial port will only get created once and it stay alive until the service is stopped.

 One lesson I learned fairly quickly was that each service running will exist in its own application domain.  Initially I was going to have several services as follows:

  • Battery service to monitor battery levels.
  • Drive service for basic forward, back, left and right drive control.
  • Camera service to pan and tilt the camera.

All these services send their commands to the Brainstem controller over the serial port, so having these as separate services would not work as each service could not share the serial port as they where running in different application domains.

For simplicity I decided  re-factor my services into one so that all my operations can use the same serial port.  Another approach would have been to have one service that managed the serial port and have my other three services talk to that service.

UPDATE:

I changed my design again and stayed with seperate services.  All of Service classes are in one project and I have implimented a singleton class using a pattern from Microsoft Patterns & Practices.  Now with this singleton I could probably drop my ServiceBehavior attribute that forces the services to run in InstanceContextMode.Single mode.  Now i don't have any service code in my app_code folder and the svc file look link this:

<%@ ServiceHost Language="C#" Debug="true" Service="N9Service.SimpleDriverService"  %>

 N9Service.SimpleDriverService is implimentedin a different project so I can easily change from hosting in IIS if I want to do that later.  I'll leave that for another post.

 

 

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

BlogEngine SQL 2000 Scripts

by Andy 22. September 2008 12:55

My host only provides SQL Server 2000 so I modified the setup scripts and thought I'd publish the changes as my first post on my new blog.  Only two general changes where required:

  1.  [nvarchar](max)columns changed to [nText].
  2. Table contrainsts changed - None of the WITH parameters are supported.

Here is a sample of the original script with the changed script below.  I have also attached the file for others to use MSSQL2000Setup1.4.5.0.sql (25.01 kb).

Orinigal:

  1. /****** Object:  Table [dbo].[be_Pages]    Script Date: 12/22/2007 14:15:17 ******/
  2. SET ANSI_NULLS ON
  3. GO
  4. SET QUOTED_IDENTIFIER ON
  5. GO
  6. CREATE TABLE [dbo].[be_Pages](
  7.     [PageID] [uniqueidentifier] ROWGUIDCOL  NOT NULL CONSTRAINT [DF_be_Pages_PageID]  DEFAULT (newid()),
  8.     [Title] [nvarchar](255) NULL,
  9.     [Description] [nvarchar](max) NULL,
  10.     [PageContent] [nvarchar](max) NULL,
  11.     [Keywords] [nvarchar](max) NULL,
  12.     [DateCreated] [datetime] NULL,
  13.     [DateModified] [datetime] NULL,
  14.     [IsPublished] [bit] NULL,
  15.     [IsFrontPage] [bit] NULL,
  16.     [Parent] [uniqueidentifier] NULL,
  17.     [ShowInList] [bit] NULL,
  18.  CONSTRAINT [PK_be_Pages] PRIMARY KEY CLUSTERED
  19. (
  20.     [PageID] ASC
  21. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  22. ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
  23. GO

Changed:

  1. /****** Object:  Table [dbo].[be_Pages]    Script Date: 12/22/2007 14:15:17 ******/
  2. SET ANSI_NULLS ON
  3. GO
  4. SET QUOTED_IDENTIFIER ON
  5. GO
  6. CREATE TABLE [dbo].[be_Pages](
  7.     [PageID] [uniqueidentifier] ROWGUIDCOL  NOT NULL CONSTRAINT [DF_be_Pages_PageID]  DEFAULT (newid()),
  8.     [Title] [nvarchar](255) NULL,
  9.     [Description] [ntext] NULL,
  10.     [PageContent] [ntext] NULL,
  11.     [Keywords] [ntext] NULL,
  12.     [DateCreated] [datetime] NULL,
  13.     [DateModified] [datetime] NULL,
  14.     [IsPublished] [bit] NULL,
  15.     [IsFrontPage] [bit] NULL,
  16.     [Parent] [uniqueidentifier] NULL,
  17.     [ShowInList] [bit] NULL,
  18.  CONSTRAINT [PK_be_Pages] PRIMARY KEY CLUSTERED
  19. (
  20.     [PageID] ASC
  21. )) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
  22. GO

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

BlogEngine

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About The Author

I am a .Net developer living in New Zealand.  Somehow I manage to find time (with 2 children) to do some coding and play with Robots.  I am using this blog to document my ideas and progress on my personal robot project.

RecentPosts