23 Replies Latest reply on May 15, 2011 1:50 AM by IOMHouston

    PISDK Error: The server is already open under a different connection string


      Hi All,


      We have an issue with the PI SDK that we tried to resolve via Tech Support. After spending a couple of days with Tech support, we were asked to post this to the vCampus folks. So here's the issue:


      We have developed an ASP.NET web application which basically has custom reports that query data from our PI Collective (2 members). Our application uses PI SDK (v1.3.8.388) to query tag data. We have the following method in .NET (which is used by our ASP.NET web application) which returns a PI Server object when our web page tries to query PI data. 


      public Server GetServer(string piuser, string pipassword)




            // We get the piuser and pipassword based on which Active Directiry group a user belongs


            // Using the above user account, we connect to PI via PISDK




            PISDKClass sdk = new PISDKClass();


            Server server = sdk.Servers[ConfigurationManager.AppSettings["PIServer"]];


            server.Open(string.Format("uid={0};pwd={1}", piuser, pipassword));


            return server;






      NOTE: We did not close the server connection after usage. We encountered some errors by forcefully closing the connection. At that time, we worked with some folks in the vCampus. They recommended that we don't have to explicitly close the server connection, once its open. We were also told that the PI SDK will manage this efficiently.



        • Re: PISDK Error: The server is already open under a different connection string

          Here are some questions that we already answered to the TECH SUPPORT FOLKS, just to save time:


          1. How many users are accessing the web application? Do they all have proper trusts/mappings set up to get access to the PI server?


          The application is deployed on IIS server. We are not using trusts. We are using PI User accounts. The IIS server connects to the PI Server using these accounts. We have created about 20 PI User accounts. We are NOT doing Windows Active Directory security at this point. We will do this for future release as our AD environment is not ready.


          2. Do you have multiple Server connection windows open?


          We call Server.Open() in the code to open a connection to the PI server.


          3. Is this a custom-built application?




          4. Do you have a trust set up for this application?




          5. What versions of PI-SDK and PI Server are you using? 32-bit or 64-bit?


          PI SDK (32 bit)


          PI Server 3.4.380.36 (64 bit)

          • Re: PISDK Error: The server is already open under a different connection string

            May I ask why aren't you using the ServerManager object as exposed in the PI SDK help instead of using the PISDK object?

              • Re: PISDK Error: The server is already open under a different connection string

                We used the the ServerManager object in the beginning. But, we learnt that it works with Active Directory. This was why we used the PISDK object. We are authenticating users with PI User account. We will eventually move away once we have Active Directory setup on our Process Network production environment.

                  • Re: PISDK Error: The server is already open under a different connection string

                    First I'd like to clear up one of the misconceptions above. The ServerManager object supports both PI Trusts and Windows Security. It was actually added to PI SDK years back, and is used by multiuser products such as PI WebParts and PI Web Services. Here is what the SDK manual says about ServerManager -




                    The ServerManager is a creatable collection object whose purpose is to provide a pool of open server connections to PI3.3 servers.  Web based business objects can provide improved performance while maintaining security by creating a single ServerManager as an application level object.  The ServerManager uses the PI3.3 PITrust table, maintained on the PI server, to validate connected domain users and provides open connections as trusted PI users.


                    The PI-SDK object hierarchy derives significant performance benefits from caching Server information as it is retrieved over time.  Typical PI-SDK client/server applications maintain a small number of connections over the execution of the application, reaping the benefits of cached data.  In a “connectionless” Web environment, reestablishing a PI-SDK hierarchy with each client access is prohibitively slow.  The ServerManager solves this problem by storing open Server objects and providing secure access to them as required.


                    That said, it looks like there are a few possible solutions (least to most effort):

                    1. Continue to use existing Server/Servers collection but close connection each time before re-opening. This is probably not viable for a web application, due to performance considerations.
                    2. Create a separate thread with its own SDK object for each user request. This would allow explicit login for each user, but may be a major effort since you would handle all the connection management like ServerManager.
                    3. Change code to use the ServerManager collection to establish a separate SDK object with unique user credentials.
                    4. Change code to use PI Web Services. This may seem like a significant change at this stage in your development, but may in fact be an easier solution since it would likely mean less custom SDK code to test and manage.

                    The last two approaches are the recommended solutions, with nod towards PI Web Services in long term...


                    As an alternative, you could change the security model so that the application connects as a specific user (i.e. service account). This account has access to all PI data. Then implement security at the application layer and ensure that only authenticated/authorized users can access the application. Of course this would effectively bypass PI security and shift the burden to the application, but it might be feasible given security features in ASP.NET such as Forms Authentication.


                    The best approach would likely be to combine security at both the application level and the PI System level, similar to how SharePoint and PI WebParts work. For example, SharePoint leverages Active Directory to authenticate users and authorize them to access a site/page, and PI WebParts passes these Windows credentials to PI System to ensure users only see the data they have access to. So hopefully this issue helps folks understand why we also recommend that customers and partners consider developing on Microsoft SharePoint/PI WebParts infrastructure, if possible.

                      • Re: PISDK Error: The server is already open under a different connection string



                        Thanks for your detailed reply. I have some more questions to understand this a bit better...


                        You had mentioned about ServerManager object and that it supports PI trust and windows security. We eventually would like to go to windows security for our future release. Our understanding was that PI Trust would expose all tags to the trusted user.


                        We have around 20 business groups at our company & there is requirement that we allow users to access Tags that they're allowed to see. This was why we created 20 PI User accounts. When a web based user tries to query PI data, we would like to connect to PI with the corresponding user account. We thought that we could accomplish this via PISDK Server object.


                        Does the ServerManager object support the use of PI User accounts ?


                        Can we get some sample code for solution 3 ?


                        We were using the following code when we had plans to do windows authentication. We didnt know that we could pass user credentials to do a "server_manager.get_Item(ref pi_server)".


                        ServerManager server_manager = (ServerManager)System.Web.HttpContext.Current.Application["ServerManager"];


                               if (server_manager == null)




                                       server_manager = new ServerManager();


                                       System.Web.HttpContext.Current.Application["ServerManager"] = server_manager;




                                   if (ConfigurationManager.AppSettings["PIServer"] == null) throw new Exception("Error connecting to PI server. Missing server name in the configuration file");


                                   object pi_server = ConfigurationManager.AppSettings["PIServer"];


                                   return server_manager.get_Item(ref pi_server);