dcsimg
Results 1 to 7 of 7

Thread: RPC - handling two different programs on the same server

  1. #1

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    RPC - handling two different programs on the same server

    I have a file named serverlib.asp in the asp folder of the server root which creates an object for my first program.
    As I understand it, the server will use the same .asp file each time and create the same object, but with different parameters.
    The only difference between the two programs is in the connection string they use in the cHandler class.
    What is the best way to handle this?

    Thanks
    PK

  2. #2

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: RPC - handling two different programs on the same server

    Olaf,

    I am publishing my files on the server now.
    Can you please advise what I must put into the manifest file and in which format.

    Thanks
    PK

  3. #3
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,405

    Re: RPC - handling two different programs on the same server

    Quote Originally Posted by Peekay View Post
    I am publishing my files on the server now.
    Can you please advise what I must put into the manifest file and in which format.
    A manifest-file is a simple text-file (containing XML).
    In this simple case, it should be placed beside the Dll in question,
    and named like the Dll-File (just with *.manifest instead of the *.dll suffix).

    You can generate such a simple Manifest for any Dll(Class) which is registered on your Dev-Machine this way:
    (Form_Load contains Code, which puts out the Manifest-Files XML-content into the Debug.Window for your specific Dll):
    Code:
    Option Explicit
    
    Private Declare Function CLSIDFromProgID Lib "ole32" (ByVal psProgID As Long, pClsID As Any) As Long
    Private Declare Function StringFromGUID2 Lib "ole32" (pClsID As Any, ByVal pStr As Long, ByVal sLen As Long) As Long
    
    Private Sub Form_Load()
      Debug.Print MakeSimpleManifest("Serverlib.cAsp")
    End Sub
    
    Function MakeSimpleManifest(ByVal ProgID As String) As String
    Dim S As String
        S = S & "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>"
        S = S & "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>"
        S = S & "  <file name = '" & Split(ProgID, ".")(0) & ".dll' >"
        S = S & "    <comClass progid = '" & ProgID & "' clsid = '" & ProgId2ClsId(ProgID) & "'  threadingModel = 'Apartment' />"
        S = S & "  </file>"
        S = S & "</assembly>"
        MakeSimpleManifest = Replace(Replace(S, "'", """"), ">", ">" & vbCrLf)
    End Function
     
    Function ProgId2ClsId(ByVal ProgID As String) As String
      Dim ClsID(0 To 15) As Byte
          CLSIDFromProgID StrPtr(ProgID), ClsID(0)
      ProgId2ClsId = Space$(38)
      StringFromGUID2 ClsID(0), StrPtr(ProgId2ClsId), Len(ProgId2ClsId) + 1
    End Function
    And as already written in another thread, the usage of this manifest-file in the *.asp-Script would be:
    Code:
    <% @EnableSessionState=False %>
    <%
      On Error Resume Next
      'try to create the SxS-Object - and provide it with the Libs-manifest-file
      Dim SxS: Set SxS = Server.CreateObject("Microsoft.Windows.ActCtx") 
          SxS.Manifest = Server.MapPath("/bin/ServerLib.manifest")
    
          'now instantiate a cASP-instance regfree via SxS - and call its HandleRequest-routine
          SxS.CreateObject("ServerLib.cASP").HandleRequest Application, Server, Request, Response
     
      If Err Then Response.Write "Error: " & Err.Description
    %>
    That said, if you have "full remote-access" to your (Windows-based) Servermachine
    (e.g. via an RDP- or VNC-or SSH/Putty-session ), then a manifest-file (for regfree usage) would not be needed at all -
    a simple registering of your ServerLib.dll on that Webserver-Host (via regsvr32 from SysWow64) would be enough.

    As for your other question (the one, which you opened this thread with)...
    I take it, that you have solved this on your own in the meantime...

    Just give other readers a bit more context in further questions - since the term "RPC" can mean "any kind of remote-calls"
    (not necessarily the specific implementation which is used by you, to talk with your Server-Dll via an MS-IIS-WebServer-instance).

    Supplying a Link to the codebank-article, which describes the Format and used Code for this kind of RPC, would be a good start:
    http://www.vbforums.com/showthread.p...g-of-http-RPCs

    HTH

    Olaf

  4. #4

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: RPC - handling two different programs on the same server

    Thanks Olaf,

    I have not solved the first post.

    My own view is that I should have a dll with a different name and an asp file with a different name, but I thought that you might have a more elegant solution.

    PK

  5. #5
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,405

    Re: RPC - handling two different programs on the same server

    Quote Originally Posted by Peekay View Post
    I have not solved the first post.

    My own view is that I should have a dll with a different name and an asp file with a different name,
    but I thought that you might have a more elegant solution.
    When nearly all of the routines in the ServerLib.dll (Classes cAsp.cls and cHandler.cls) are generic,
    commonly usable ones - and just the ADO-Connection "underneath" needs to be switched at the serverside
    (depending on certain criteria)...

    ...then the best way to approach this is, to keep this stuff in that "single-universal Dll" -
    just adding some enhancements, which prepare the Dll-Classes (pre-setting certain things),
    depending on "outside-criterions, which came from the clientside".

    There is always some "Client-context-stuff" which deserves "special attention" as e.g.:
    - which kind of ClientApp(-Executable) is using your Server-RPC-API - and does it need to be routed to a specific DB(-Catalogue)
    - which kind of Customer is currently using your Client-App - and does he need his own DB(-Catalogue) at the serverside as well
    - which kind of User is currently active (using your ClientApp) - and does he require authentification/authorization at the serverside

    So, what I suggest is, to enhance the cHandler-Class about a few additional Public Variables (Public Properties),
    which get set from within the "Entry-Class" of the ServerLib.dll (the Class, named cAsp), before the cHandler-Class-
    Method in question gets invoked.

    You could define these new Public Vars at the top of the cHandler.cls e.g. as:
    Code:
    Public AppID As String, CustomerID As String
    Public UserName As String, UserToken As String
    Public Cnn As ADODB.Connection
    What remains is, to fill these new cHandler- Public - Props from within cAsp (in its single HandleRequest-Method) -
    for example:
    Code:
    Public Sub HandleRequest(Application As Object, Server As Object, Request As Object, Response As Object)
      On Error Resume Next
      Dim Handler As New cHandler 'fill a new Handler-Instance with the (deserialized) incoming RsParams (which were set at the clientside)
      Set Handler.RsIn = GetRsFromByteContent(Request.BinaryRead(Request.TotalBytes))
          
          Handler.AppID = Request.ServerVariables("HTTP_RPC-AppID")
          Handler.CustomerID = Request.ServerVariables("HTTP_RPC-CustomerID")
          Handler.UserName = Request.ServerVariables("HTTP_RPC-UserName")
          Handler.UserToken = Request.ServerVariables("HTTP_RPC-UserToken")
      
      Const ConnStringSettingsDB = "YourSettings-DB-Connstring"
      Dim CnnSettings As ADODB.Connection, RsSettings As ADODB.Recordset
      Set CnnSettings = modADODB.OpenCnn(ConnStringSettingsDB)
      Set RsSettings = modADODB.GetRs(CnnSettings, "Select CnnString From CnnStrings Where AppID=? And CustomerID=?", Handler.AppID, Handler.CustomerID)
      
      If RsSettings.RecordCount = 0 Then 'we have not found a valid Cnn for the given AppID and CustomerID
         Response.BinaryWrite GetByteContentFromRs(CreateErrorRs("DB-Connection-Info not found", vbObjectError))
         Err.Clear
         Exit Sub
      End If
      Err.Clear
      
      'we have found a record with a valid Connections-String in our Settings-DB
      Set Handler.Cnn = OpenCnn(CStr(RsSettings!CnnString.Value)) 'let's try to set the Cnn-Object-Property in the Handler-Class
      If Err Then 'Error establishing the specific Handler-Connection for this request
         Response.BinaryWrite GetByteContentFromRs(CreateErrorRs(Err.Description, Err.Number))
         Err.Clear
         Exit Sub
      End If
      Err.Clear
      
      'since the incoming Rs contains the ProcedureName as a String, we use that in a CallByName-call on the Handler-Instance
      CallByName Handler, Handler.RsIn!ProcName.Value, VbMethod
      
      If Err Then
        Response.BinaryWrite GetByteContentFromRs(CreateErrorRs(Err.Description, Err.Number))
        Err.Clear
      ElseIf Not Handler.RsOut Is Nothing Then
        Response.BinaryWrite GetByteContentFromRs(Handler.RsOut)
      End If
    End Sub
    The code in blue above is the old, existing one - the magenta- and black-colored text is new code-additions.

    The Clientside needs to fill-in the magenta-colored Header-Variables appropriately
    (in your Client-Apps cRPC.cls ... inside the DoRPC()-routine):
    Code:
        Dim http As New WinHttpRequest
            http.Open "POST", RPCUrl, True
            http.SetRequestHeader "Content-Type", "application/octet-stream"
            http.SetRequestHeader "Cache-Control", "private"
            
            'new, Dll-Handler-Specific Extra-Headers:
            http.SetRequestHeader "RPC-AppID", "MyAppID_1"
            http.SetRequestHeader "RPC-CustomerID", "MyCustomerID_1"
            http.SetRequestHeader "RPC-UserName", "MyUserName_1"
            http.SetRequestHeader "RPC-UserToken", "MyUserToken_1"
           
            http.Send GetByteContentFromRs(RsParams) '...
    Same ColorScheme in the above Code-snippet as before (old, existing code in blue).

    Regarding some background-info, on what was done there (with these extra-parameters and their transport),
    you should study-up with regards to "http-headers"... (using google for example) - specifically:
    - how those are set when the WinHttp51-Object is used for client-initiated http-requests
    - and how they later can be read-out from within the ASP-Request-Object on the IIS
    ... as already shown in the code above.

    I will not always be around "in person" to answer your questions - so you *have* to study this stuff at least to the extend,
    that you can explain your (future) problems roughly to other developers as well (regarding, what was used, what the context is, etc.)...

    HTH

    Olaf

  6. #6

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: RPC - handling two different programs on the same server

    Thanks Olaf,
    I will do so.
    And ... I think the past few months I have really learned a lot thanks to your persistence in helping me.
    I still need some practical experience before I can say I know it well.
    There are also many other members on this forum who are really experts, but they might not have kept up with the context of our excursion.
    I hope you stick around for much longer. We newbies or uninitiates need you and many other veterans here. That is what makes this forum great.

    Pk

  7. #7

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: RPC - handling two different programs on the same server

    Olaf,

    Your code reads the required connection string from a table named CnnStrings.

    Code:
    Set RsSettings = modADODB.GetRs(CnnSettings, "Select CnnString From CnnStrings Where AppID=? And CustomerID=?", Handler.AppID, Handler.CustomerID)
    I am not sure where this table is stored on the server. It must be some separate database or XML file. Is that correct?

    Your code also provides for authentication. I have not done any such on the server side untill now and would presume it is only to prevent hacking. Are there other considerations? I authenticate my users in the Client application itself when the program opens. I do not use windows authentication for my client program.

    Is this information stored in a database or XML file on the server?

    I am not sure what Customer or CustomerID means in this context.

    Thanks

    PK

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width