<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    snowolf

    這樣的一種生活
    posts - 23, comments - 5, trackbacks - 0, articles - 11

    Live Communications Server Application API (1)

    Posted on 2006-01-17 09:43 snowolf 閱讀(433) 評論(0)  編輯  收藏 所屬分類: 其他

    Live Communications Server Application API
    發布時間:2005 年 6 月

     
    LCS API套件中包括:
    Microsoft SIP Processing Language(MSPL)、Microsoft.Rtc.Sip命名空間、application manifests 和為LCS構建SIP應用程序的資料。
    Note   The Live Communications Server Application API currently does not support SIP dialogs and UAC server behaviors. Future versions of the API will add support for these features.
    1. Application manifests
    The application manifest is an XML document that describes a Live Communications Server application to the server on which it is running. This document is presented to the server when the application registers with Live Communications Server through the Microsoft.Rtc.Sip.ServerAgent managed class.
    1.1 Application manifests構成:
    Application manifests由以下三部分組成:
    1.1.1 <alias:applicationManifest>標簽。
    在這個標簽內裝入應用程序屬性(Application attributes)和消息過濾腳本(MSPL),可以為"alias"定義一個別名,微軟建議使用默認別名"ls"。
    1.1.2 A set of application attributes that defines key properties of the application, such as the SIP message types to filter and whether it is script-only.
    1.1.3 用MSPL語言寫的消息過濾腳本。
    在CDATA element里被附加上<alias:splScript>標簽。
    1.2 Application manifests部屬:
    這個Application manifests文件,一次建立后,可以和裝配件(assembly)里的resource一樣,植入應用程序內部,或者像一個外部文件一樣存在。
    1.2.1 植入assembly內部:
    用Microsoft.Rtc.Sip命名空間的ApplicationManifest類,在新生成的 ApplicationManifest對象里用Compile方法對它進行編譯。樣里代碼如下:
            ResourceManager myResourceManager = new ResourceManager(MyApplicationType);
            
    string appManifestXml = myResourceManager.GetString("appManifest");
            ApplicationManifest myAppManifest 
    = ApplicationManifest.CreateFromString(appManifestXml);
            
    try {
                myAppManifest.Compile();
            }

            
    catch (CompilerErrorException cee) {
                Console.WriteLine(
    "Failed to compile.");
                
    foreach (string message in cee.ErrorMessages) {
                    Console.WriteLine(message);
                }

                
    return
    ;
            }

                   
                   編譯成功后,這個編譯過的Application manifests部屬到代理服務器上,
    1.2.2 外部文件格式:
    下面是一個僅有SIP INVITE and MESSAGE請求的基本的application manifest:
                   <?xml version="1.0" ?>
                   
    <
    lc:applicationManifest
                 
    appUri="http://www.adatum.com/myApplicationLocation"

                 xmlns:lc
    ="http://schemas.microsoft.com/lc/2003/05">

                      
    <lc:requestFilter methodNames="INVITE,MESSAGE"
     
                                  strictRoute
    ="false"
     
                            registrarGenerated
    ="true"

                            domainSupported
    ="true">

                      
    <lc:responseFilter reasonCodes="NONE" />

                      
    <lc:proxyByDefault action="true" />

                    
    <lc:scriptOnly />

                 
    <lc:splScript><![CDATA[

                                  if (sipRequest) {
                                if (sipRequest.Method == StandardMethod.Invite) {
                              Dispatch("NameOfInviteHandlerMethodInApplicationHere");
                                }
                                     else if (sipRequest.Method == StandardMethod.Message) {
                                        Dispatch("NameofMessageHandlerMethodInApplicationHere");
                                }
                                  }
                 
    ]]></lc:splScript>

                   
    </lc:applicationManifest>
    1.3 Application Attributes
    Application Attibutes在消息過濾腳本的前面,在<lc:applicationManifest>標簽的后面,包含詳細的描述LCS應用程序的數據。例如下面所示:
                   <?xml version="1.0" ?>
                   
    <
    lc:applicationManifest
                    
    lc:appUri="http://www.adatum.com/applicationName"

                    xmlns:lc
    =http://schemas.microsoft.com/lcs/2004/05>
                     
    application attributes
                   <lc:splScript
    ><![CDATA[

                     message filter script
                   
    ]]></lc:splScript>

    </lc:applicationManifest>

           
           其中,xmlns屬性指定了用那個版本的LCS來運行應用程序,如果是LCS2003就采用下面的方式:
           xmlns:lc=http://schemas.microsoft.com/rtc/2003/05
    共有下列應用程序屬性標簽可供Application manifests使用:
    1.3.1
     <lc:proxyByDefault  action="true|false" />

    說明:為應用程序指定默認代理行為。
    如果是true,服務器自動代理任意消息,應用程序不依據句柄執行。如果是false,消息被拋出,應用程序結束,同時,一方將不會收到它。
    1.3.2
    <lc:scriptOnly />

    說明:當部署時,指定應用程序不含托管代碼的成分。
    1.3.3
    <lc:requestFilter methodNames="METHOD_NAMES|NONE|ALL" registrarGenerated="true|false"       strictRoute="true|false"  domainSupported="true|false" />

    說明:指定應用程序通過服務器的那些請求。
    有下列methodNames
    REGISTER
    SUBSCRIBE
    NOTIFY
    BENOTIFY
    ACK
    BYE
    INVITE
    OPTIONS
    MESSAGE
    SERVICE
    INFO
    REFER
    OTHER
    1.3.4
    <lc:responseFilter reasonCodes="RESPONSE_CLASSES|ALL|NONE" />

    說明:定義應用程序通過服務器響應那個類別。
    類別如下:
    1XX
    2XX
    3XX
    4XX
    5XX
    6XX
    1.3.5
     <lc:file path="filePath"  keyColumnName=[columName] delimitedBy="comma/tab/whitespace"
                  <column name
    ="columnName"/>
     
    <lc:column name="ColumnName"/>

    </lc:file>

    說明:Name屬性指引用的text文件名稱,必須是有效的MSPL。Path屬性是這個文件的決對路徑,如果是相對的,它必須是相對于運行RTCSRV.exe的路徑。
    1.3.6
    <lc:column name="columnName"

    用這個標簽可以指定一個或多個列節點。

    2. Microsoft SIP Processing Language
           MSPL是用來過濾或路由SIP消息的腳本語言,像大家知道的"message filters",這個腳本是植入到application manifests里的LCS應用程序中。
    MSPL不支持:
    Explicit (declarative) data types
    Type casting
    Pointers
    Declarations (other than basic function declarations, as detailed below)
    Arithmetic operations
    Iteration statements
    Preprocessor statements
    Attributes
    Static or global variables (state is not maintained across script invocations)
    2.1 MSPL Script Syntax
    2.1.1 Function Invocation
     一個函數在MSPL里是唯一的,在MSPL里函數用如下語法格式來定義:
    function ParseDisplayName (displayName) 
                   }

    所有的函數定義必須在消息過濾腳本的開始處,在過濾腳本之前。一個函數能有零個或更多的參數。為了防止無意中的循環,遞歸函數的調用是不允許的。互相的遞歸調用calls-calls模式也是不允許的。例如,如果函數1調用函數2,然后調用函數3,函數3不能調用1或2的任意一個。返回值類型是implicitly defined的,更確切的說,這個類型是傳遞的返回聲明的值決定的。參數也是implicitly defined的。函數不能返回collections,它支持的的返回類型有strings,bools,integers和floats.
    下面的函數示例過濾了一個特殊的string,如果這個string被找到返回true,否則,返回false.
                   function FilterString (content) 
                   
    {
                                  filterWord 
    ="confidential"

                                   
    return ContainsString(content, filterWord, true
    );
                   }
    2.1.2 The foreach Statement
           在SIP消息處理過程中foreach允許腳本編寫者比較句柄collections,例如contact header collections和 endpoint collections。下面示例演示了foreach loop的語法構成。
           foreach (element in expression) statement
    For example:
                   
    foreach (dbEndpoint in

                   QueryEndpoints(
    "someone@example.com"))  }
           這段代碼將求出collections里的值,Strings和其他unary types 像single-item collections一樣的處理。
    2.1.3 The break Statement
    Break 的用法和C#中switch/case里的用法相同
    2.1.4 The null Keyword
    Null關鍵字,腳本語法能添加一個null關鍵字,與empty string ("")不同,empty string是不能建立的。有下列函數將返回一個null來表明值沒有找到或者錯誤。
    " GetDisplayName
    " GetHostName
    " GetParameterValue
    " GetScheme
    " GetUri
    " GetUriParameter
    " GetUserName
    " GetUserAtHost
    " GetXMLAttr
    " QueryHomeServer
    另外,Message.Stamp 和 Message.StampPool也返回null.

    要:本文檔將介紹從最初建造一個application manifest到最終安裝和管理SIP application的詳細過程,并提供示例代碼,以演示開發擴展LCS應用的具體方法。


    Live Communications Server Application API應用
    1 在新的服務器布局里開發應用程序
    Live Communications Server 2005支持新的服務器角色,包括:Standard Edition, Enterprise Edition, Enterprise Edition Pool, Enterprise Edition Back End Storage, Archiving Service, Director, Proxy, and Access Proxy。第三方應用程序能配置到上述任意或全部服務器上,以滿足想得到的功能性。理解每個新的服務器角色的功能是開發和設計應用程序的要點。
    2 建立一個Application Manifest
    以LCS默認核心消息過濾腳本為例(此腳本原始位置:..\Program Files\Microsoft LC 2005\Server\ routing.am):
    這個MSPL腳本過濾引入的SIP消息,并且以端點ID(EDID)、可用性合計、活動性數值和AgeOfPresence數值為基礎,嘗試為每一個消息選擇出最好的端點。端點沒有注冊存在或者可用性合計小于100的將不被考慮。
    示例代碼

    <?xml version="1.0">
    <lc:applicationManifest
     lc:appUri="http://www.my_domain_here.com/DefaultRoutingScript"
     xmlns:lc="http://schemas.microsoft.com/lc/2003/05">
    <lc:requestFilter methodNames="INVITE,MESSAGE,INFO,REFER,ACK,BYE,OTHER" 
                            strictRoute="false" 
                            registrarGenerated="true"
                            domainSupported="true"/ >
    <lc:responseFilter reasonCodes="NONE" />
    <lc:proxyByDefault action="true" />
    <lc:scriptOnly />
    <lc:splScript><![CDATA[
        //Log函數向LCS指定Server Log寫入調試Log,具體內容除消息內容之外的全部消息。 
        Log( "Debug", 1, "we have a request - ", sipRequest.Method );

    //Ge tUri方法返回消息頭中的“To”
    toUri = GetUri( sipRequest.To );
    //Concatenate方法將用GetUserName得到的Sip中的toUri與@與GetHostName中的HostName
    //組合成toUserAtHost
        toUserAtHost = Concatenate( GetUserName( toUri ), "@", GetHostName( toUri ) );

    // rameterValue方法返回消息頭重指定的參數”EPID”的值。
        requestEPID = GetParameterValue( sipRequest.To, "EPID" );

     //定義變量并賦初值
    bestEPID = "";
        bestAgeOfPresence = 0x7FFFFFFF;
        bestAvailability = 0;
        bestActivity = 0;
        bestContactInfo = "";
        Log( "Debug", 1, "EPID - ", requestEPID );
    Log( "Debug", 1, "toUserAtHost - ", toUserAtHost );
    //循環全部端點
        foreach (dbEndpoint in QueryEndpoints( toUserAtHost, true )) {
            Log( "Debug", 1, "    endpoint.EPID - ", dbEndpoint.EPID );
            Log( "Debug", 1, "    endpoint.HasPresence - ", dbEndpoint.HasPresence );
            Log( "Debug", 1, "    endpoint.Availability - ", dbEndpoint.Availability );
            Log( "Debug", 1, "    endpoint.Activity - ", dbEndpoint.Activity );
            Log( "Debug", 1, "    endpoint.AgeOfPresence - ", dbEndpoint.AgeOfPresence );
            Log( "Debug", 1, "    endpoint.ContactInfo - ", dbEndpoint.ContactInfo );

     // 第一步,用SupportsMethod函數確定SIP方法是否被應用程序支持。
            if (!SupportsMethod( sipRequest.Method, dbEndpoint.StandardMethods, dbEndpoint.ExtraMethods )) {
      //跳出這個端點,因為不能處理請求的方法。
                Log( "Debug", 1, "        * skipped because of method" );
                continue;
                }
            if (requestEPID != "") {
                if (requestEPID == dbEndpoint.EPID) {
           //這個請求已經把一個能處理這個方法的端點當作目標,所以用這個端點。
                    Log( "Debug", 1, "        * matched EPID" );
     //給前面定義的變量賦值
                    bestContactInfo = dbEndpoint.ContactInfo;
                    break;
                }
                else {
     //請求已確定EPID,但不匹配,跳出這個端點,繼續執行。
                    Log( "Debug", 1, "        * skipped because of EPID" );
                    continue;
                }
            }

            if (!dbEndpoint.HasPresence ||
                dbEndpoint.Availability < 100 ||
                dbEndpoint.ContactInfo == ""
               ) {
                //如果在ContactInfo字段中沒有在線,或者狀態為“offline”,或者沒有路由信息,跳出這個端點
                 Log( "Debug", 1, "        * skipped because of presence, activity or contactinfo" );
                continue;
            }

            if (dbEndpoint.Availability < bestAvailability) {
                //如果沒有可用性條出這個端點
                Log( "Debug", 1, "        * skipped because of availability" );
                continue;
            }

            if (dbEndpoint.Availability == bestAvailability) {
                if (dbEndpoint.Activity < bestActivity) {
                    //如果這個端點活躍性小于1,跳出這個端點
                    Log( "Debug", 1, "        * skipped because of activity" );
                    continue;
                    }
    ……(略)

    3 為Live Communications Server 創建一個SIP應用程序
    3.1 Setting up a Server Agent
    server agent是你的應用程序和LCS之間的公共點。它是用ServerAgent類定義的對象,由它通過LCS代表你的應用程序發送和接收消息。
    配置一個 LCS Agent的第一步是建立一個application manifest并編譯。這個application manifest將要運行在服務器上并且通過消息過濾腳本僅接收你的應用程序感興趣的SIP消息。這個動作是通過執行你的應用程序的Main方法實現的。例如下面代碼:
    using System.Threading;
    using System.Resources;
    using Microsoft.Rtc.Sip;


    // 在這個例子中獲取包含你的application manifest的XML string,
    // 這個XML string //像資源一樣包含在應用程序裝配件中,用 
    // ResourceManager.GetString(resourceName)方法得到。

    ResourceManager myResourceManager 
    = new ResourceManager(myApplicationClass);

    //” appManifest”是你的application manifest XML 文件的名字,像添加應用程序// 的資源一樣的添加它。

    string myAppManifestXmlString = myResourceManager.GetString("appManifest");

    ApplicationManifest myAppManifest 
    = new ApplicationManifest(myAppManifestXmlString);
     
    try {
    //編譯
     myAppManifest.Compile();
    }

    //異常處理
    catch (CompilerErrorException cee) {
     Console.WriteLine(
    "The following errors occurred during compilation:");
     
    foreach (string errorMessage in cee.ErrorMessages) {
        Console.WriteLine(
    "--- {0}"
    , errorMessage);
     }

    }

     

    在實例化ServerAgent的時候提供ApplicationManifest對象,ServerAgent的構造函數會編譯這個Application Manifest.例如下面代碼。

    try {
     ServerAgent myAppServerAgent 
    = new
     ServerAgent(myAppManifest);
    }
     
    catch (NullReferenceException nre) 
    {
     Console.WriteLine(
    "The application manifest is uncompiled and ServerAgent cannot be instantiated."
    );
    }
     
    catch (ServerNotFoundException snfe) 
    {
     Console.WriteLine(
    "The Live Communications Server is not available."
    );
    }

     

    應用程序必須從消息過濾中分配句柄信息,同時,還必須建立一個類和這個句柄的方法對應。例如下面代碼,如果你有一個call在你的消息過濾器里。
    Dispatch("OnInviteReceived");
    在你的定義的類上必須有一個相應的OnInviteReceived方法。


    3.2 Processing Server Events
    當Dispatch被腳本呼叫過,一個服務器事件便被觸發。
    3.3 Handling Messages from the Live Communications Server
    當LCS收到消息,application manifest必須有特定的轉發給相應得應用程序。
    例如在application manifest中有下列代碼:

    if (sipRequest.Method == "MESSAGE")
     Dispatch(
    "OnMessageReceived"
    );
     Respond(
    200
    );
    }


    上述代碼功能是, 當LCS分配SIP消息類型為“MESSAGE”的消息給“OnMessageReceived”你的應用程序的事件句柄,定義事件句柄的代碼示例如下:

    public void OnMessageReceived(object sender, RequestReceivedEventArgs requestEventArgs) {

     
    // Obtain the Request object to process from RequestReceivedEventArgs.

     Request request = requestEventArgs.Request;
     
     
    // Obtain the new server transaction for this request.

     ServerTransaction myServerTransaction = requestEventArgs.ServerTransaction;

     
    //
     Processing logic here.
     
    //
     

     
    // Create a branch on the server transaction to forward the request.

     try
     
    {
        
    // Attempt to send the request.

        requestEventArgs.ServerTransaction.CreateBranch();
        requestEventArgs.SendRequest(request);
     }

     
    catch (Exception e)
     
    {
        Console.WriteLine(
    "Unexpected exception: {0}\n{1}"

                                e.Message,
                                e.StackTrace);
     }
     
    }


    參考文檔《Microsoft Office Live Communications Server 2005》 
    主站蜘蛛池模板: 国产在线国偷精品产拍免费| 97免费人妻在线视频| 日韩免费视频在线观看| 大地资源在线资源免费观看| 亚洲综合区小说区激情区| 久久伊人久久亚洲综合| 久久青草精品38国产免费| 亚洲AV成人无码久久精品老人| 国产又粗又长又硬免费视频| 理论秋霞在线看免费| 国产一精品一AV一免费孕妇| 国产成人精品免费大全| 中文有码亚洲制服av片| 亚洲国产第一站精品蜜芽| 精品国产麻豆免费网站| 99久久国产免费-99久久国产免费| 亚洲av无码专区在线电影| 亚洲五月六月丁香激情| 又粗又黄又猛又爽大片免费| **真实毛片免费观看| 国产精品福利在线观看免费不卡| 亚洲一区免费在线观看| 亚洲色婷婷一区二区三区| 日韩伦理片电影在线免费观看| 无码精品国产一区二区三区免费 | 一级毛片a免费播放王色| 亚洲欧洲日韩在线电影| 国产成人精品日本亚洲专区61| 成在人线AV无码免费| 免费A级毛片无码A∨中文字幕下载| 久久精品亚洲日本波多野结衣| 亚洲视频一区二区在线观看| 国产综合精品久久亚洲| 国产午夜免费秋霞影院| 999国内精品永久免费视频| 亚洲黄色免费网站| a级毛片免费观看视频| 特黄aa级毛片免费视频播放| 亚洲一区二区观看播放| 亚洲国产精品美女| 亚洲一区二区成人|